@mictonode/widget 0.3.15 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +3 -3
- package/.github/workflows/npm-publish.yml +34 -34
- package/.prettierrc.json +9 -9
- package/.vscode/extensions.json +3 -3
- package/LICENSE +674 -674
- package/README.md +41 -41
- package/dist/{main-3096050c.js → main-465ae991.js} +155 -150
- package/dist/ping-widget.js +2 -2
- package/dist/ping-widget.umd.cjs +17 -17
- package/dist/{query.lcd-1625d320.js → query.lcd-d9c6163c.js} +1 -1
- package/dist/{query.rpc.Query-45d48ded.js → query.rpc.Query-a479e6f9.js} +1 -1
- package/dist/{tx.rpc.msg-0e09f357.js → tx.rpc.msg-7444045d.js} +1 -1
- package/example/.vscode/extensions.json +3 -3
- package/example/README.md +7 -7
- package/example/index.html +12 -12
- package/example/package.json +19 -19
- package/example/pnpm-lock.yaml +465 -465
- package/example/public/cdn.html +19 -19
- package/example/src/App.vue +73 -73
- package/example/src/main.js +4 -4
- package/example/vite.config.js +7 -7
- package/index.html +12 -12
- package/lib/components/ConnectWallet/index.vue +262 -262
- package/lib/components/TokenConvert/index.vue +1033 -1033
- package/lib/components/TokenConvert/tokens.ts +36 -36
- package/lib/components/TxDialog/index.vue +13 -9
- package/lib/components/TxDialog/messages/Delegate.vue +174 -174
- package/lib/components/TxDialog/messages/Deposit.vue +96 -96
- package/lib/components/TxDialog/messages/Redelegate.vue +160 -160
- package/lib/components/TxDialog/messages/Send.vue +142 -142
- package/lib/components/TxDialog/messages/Transfer.vue +248 -248
- package/lib/components/TxDialog/messages/Unbond.vue +103 -103
- package/lib/components/TxDialog/messages/Vote.vue +62 -62
- package/lib/components/TxDialog/messages/Withdraw.vue +55 -55
- package/lib/components/TxDialog/messages/WithdrawCommission.vue +74 -74
- package/lib/components/TxDialog/wasm/ClearAdmin.vue +55 -55
- package/lib/components/TxDialog/wasm/ExecuteContract.vue +98 -98
- package/lib/components/TxDialog/wasm/InstantiateContract.vue +108 -108
- package/lib/components/TxDialog/wasm/MigrateContract.vue +76 -76
- package/lib/components/TxDialog/wasm/MigrateContract2.vue +76 -76
- package/lib/components/TxDialog/wasm/StoreCode.vue +100 -100
- package/lib/components/TxDialog/wasm/UpdateAdmin.vue +74 -74
- package/lib/main.css +132 -7
- package/lib/main.ts +23 -23
- package/lib/utils/TokenUnitConverter.ts +44 -44
- package/lib/utils/format.ts +16 -16
- package/lib/utils/http.ts +154 -154
- package/lib/utils/type.ts +56 -56
- package/lib/wallet/EthermintMessageAdapter.ts +135 -135
- package/lib/wallet/UniClient.ts +144 -144
- package/lib/wallet/Wallet.ts +142 -133
- package/lib/wallet/wallets/KeplerWallet.ts +141 -141
- package/lib/wallet/wallets/LeapWallet.ts +141 -141
- package/lib/wallet/wallets/LedgerWallet.ts +202 -202
- package/lib/wallet/wallets/MetamaskSnapWallet.ts +105 -105
- package/lib/wallet/wallets/MetamaskWallet.ts +173 -173
- package/lib/wallet/wallets/OKXWallet.ts +202 -202
- package/lib/wallet/wallets/UnisatWallet.ts +198 -198
- package/package.json +3 -3
- package/postcss.config.js +6 -6
- package/src/App.vue +225 -225
- package/src/main.ts +7 -4
- package/src/styles/design-system.css +150 -0
- package/src/vite-env.d.ts +1 -1
- package/tailwind.config.js +211 -34
- package/tsconfig.json +25 -25
- package/tsconfig.node.json +10 -10
- package/vite.config.ts +62 -62
- package/vue-shim.d.ts +6 -6
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
export interface TokenConfig {
|
|
2
|
-
denom: string;
|
|
3
|
-
symbol: string;
|
|
4
|
-
ibcDenom: string;
|
|
5
|
-
decimals: number;
|
|
6
|
-
coinImageUrl: string;
|
|
7
|
-
sourceChannelId?: string;
|
|
8
|
-
destChannelId?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const tokens : TokenConfig[]= [
|
|
12
|
-
{
|
|
13
|
-
denom: "uosmo",
|
|
14
|
-
symbol: "OSMO",
|
|
15
|
-
ibcDenom: "uosmo", // use base denom for native token
|
|
16
|
-
decimals: 6,
|
|
17
|
-
coinImageUrl: "https://app.osmosis.zone/tokens/osmo.svg",
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
denom: "uatom",
|
|
21
|
-
symbol: "ATOM",
|
|
22
|
-
ibcDenom: "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2",
|
|
23
|
-
sourceChannelId: "channel-0",
|
|
24
|
-
destChannelId: "channel-141",
|
|
25
|
-
decimals: 6,
|
|
26
|
-
coinImageUrl: "https://app.osmosis.zone/tokens/atom.svg",
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
denom: "uusdc",
|
|
30
|
-
symbol: "USDC",
|
|
31
|
-
ibcDenom: "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858",
|
|
32
|
-
sourceChannelId: "channel-208",
|
|
33
|
-
destChannelId: "",
|
|
34
|
-
decimals: 6,
|
|
35
|
-
coinImageUrl: "https://app.osmosis.zone/tokens/usdc.svg",
|
|
36
|
-
},
|
|
1
|
+
export interface TokenConfig {
|
|
2
|
+
denom: string;
|
|
3
|
+
symbol: string;
|
|
4
|
+
ibcDenom: string;
|
|
5
|
+
decimals: number;
|
|
6
|
+
coinImageUrl: string;
|
|
7
|
+
sourceChannelId?: string;
|
|
8
|
+
destChannelId?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const tokens : TokenConfig[]= [
|
|
12
|
+
{
|
|
13
|
+
denom: "uosmo",
|
|
14
|
+
symbol: "OSMO",
|
|
15
|
+
ibcDenom: "uosmo", // use base denom for native token
|
|
16
|
+
decimals: 6,
|
|
17
|
+
coinImageUrl: "https://app.osmosis.zone/tokens/osmo.svg",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
denom: "uatom",
|
|
21
|
+
symbol: "ATOM",
|
|
22
|
+
ibcDenom: "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2",
|
|
23
|
+
sourceChannelId: "channel-0",
|
|
24
|
+
destChannelId: "channel-141",
|
|
25
|
+
decimals: 6,
|
|
26
|
+
coinImageUrl: "https://app.osmosis.zone/tokens/atom.svg",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
denom: "uusdc",
|
|
30
|
+
symbol: "USDC",
|
|
31
|
+
ibcDenom: "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858",
|
|
32
|
+
sourceChannelId: "channel-208",
|
|
33
|
+
destChannelId: "",
|
|
34
|
+
decimals: 6,
|
|
35
|
+
coinImageUrl: "https://app.osmosis.zone/tokens/usdc.svg",
|
|
36
|
+
},
|
|
37
37
|
]
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
getTxByHash,
|
|
11
11
|
} from '../../utils/http';
|
|
12
12
|
import { BroadcastMode, Coin, CoinMetadata } from '../../utils/type';
|
|
13
|
-
import { WalletName, readWallet } from '../../../lib/wallet/Wallet';
|
|
13
|
+
import { WalletName, readWallet, isEvmChain } from '../../../lib/wallet/Wallet';
|
|
14
14
|
import { UniClient } from '../../../lib/wallet/UniClient';
|
|
15
15
|
|
|
16
16
|
// cosmos sdk messages
|
|
@@ -149,6 +149,10 @@ async function initData() {
|
|
|
149
149
|
}
|
|
150
150
|
getLatestBlock(props.endpoint).then((x) => {
|
|
151
151
|
chainId.value = x.block.header.chain_id;
|
|
152
|
+
// Set higher default fee for EVM chains (Warden, Evmos, etc.)
|
|
153
|
+
if (isEvmChain(chainId.value) && feeAmount.value < 250000) {
|
|
154
|
+
feeAmount.value = 250000;
|
|
155
|
+
}
|
|
152
156
|
});
|
|
153
157
|
|
|
154
158
|
// Every sub component should have a initial function
|
|
@@ -289,8 +293,8 @@ function fetchTx(tx: string) {
|
|
|
289
293
|
<!-- Put this part before </body> tag -->
|
|
290
294
|
<input v-model="open" type="checkbox" :id="type" class="modal-toggle" @change="initData()" />
|
|
291
295
|
<label :for="type" class="modal cursor-pointer">
|
|
292
|
-
<label class="modal-box relative p-5 dark:bg-[#
|
|
293
|
-
<label :for="type" class="btn dark:bg-
|
|
296
|
+
<label class="modal-box relative p-5 dark:bg-[#0f1419]" :class="{ '!w-11/12 !max-w-5xl': String(type).startsWith('wasm') }" for="">
|
|
297
|
+
<label :for="type" class="btn dark:bg-primary-500 dark:hover:bg-neutral-800 btn-sm btn-circle absolute right-4 top-4">✕</label>
|
|
294
298
|
<h3 class="text-lg font-bold capitalize dark:text-gray-300">
|
|
295
299
|
{{ showTitle() }}
|
|
296
300
|
</h3>
|
|
@@ -311,9 +315,9 @@ function fetchTx(tx: string) {
|
|
|
311
315
|
</label>
|
|
312
316
|
<label class="input-group flex items-center">
|
|
313
317
|
<input v-model="feeAmount" type="text" placeholder="0.001"
|
|
314
|
-
class="input border border-gray-300 dark:border-
|
|
318
|
+
class="input border border-gray-300 dark:border-neutral-700 flex-1 w-0 dark:text-gray-300" />
|
|
315
319
|
<select v-model="feeDenom"
|
|
316
|
-
class="select input border border-gray-300 dark:border-
|
|
320
|
+
class="select input border border-gray-300 dark:border-neutral-700 w-[200px]">
|
|
317
321
|
<option disabled selected>
|
|
318
322
|
Select Fee Token
|
|
319
323
|
</option>
|
|
@@ -328,21 +332,21 @@ function fetchTx(tx: string) {
|
|
|
328
332
|
<span class="label-text">Gas</span>
|
|
329
333
|
</label>
|
|
330
334
|
<input v-model="gasInfo" type="number" placeholder="2000000"
|
|
331
|
-
class="input border border-gray-300 dark:border-
|
|
335
|
+
class="input border border-gray-300 dark:border-neutral-700 dark:text-gray-300" />
|
|
332
336
|
</div>
|
|
333
337
|
<div class="form-control">
|
|
334
338
|
<label class="label">
|
|
335
339
|
<span class="label-text">Memo</span>
|
|
336
340
|
</label>
|
|
337
341
|
<input v-model="memo" type="text" placeholder="Memo"
|
|
338
|
-
class="input border border-gray-300 dark:border-
|
|
342
|
+
class="input border border-gray-300 dark:border-neutral-700 dark:text-gray-300" />
|
|
339
343
|
</div>
|
|
340
344
|
<div class="form-control">
|
|
341
345
|
<label class="label">
|
|
342
346
|
<span class="label-text">Broadcast Mode</span>
|
|
343
347
|
</label>
|
|
344
348
|
<select v-model="broadcast"
|
|
345
|
-
class="select input border border-gray-300 dark:border-
|
|
349
|
+
class="select input border border-gray-300 dark:border-neutral-700 w-[200px]">
|
|
346
350
|
<option :value="BroadcastMode.SYNC">Sync</option>
|
|
347
351
|
<option :value="BroadcastMode.ASYNC">Async</option>
|
|
348
352
|
<option :value="BroadcastMode.BLOCK">Block</option>
|
|
@@ -368,7 +372,7 @@ function fetchTx(tx: string) {
|
|
|
368
372
|
class="checkbox checkbox-sm checkbox-primary mr-2" /><label :for="`${type}-advance`"
|
|
369
373
|
class="cursor-pointer dark:text-gray-400">Advance</label>
|
|
370
374
|
</div>
|
|
371
|
-
<button class="btn btn-primary dark:bg-
|
|
375
|
+
<button class="btn btn-primary dark:bg-primary-500" @click="sendTx()" :disabled="sending">
|
|
372
376
|
<span v-if="sending" class="loading loading-spinner"></span>
|
|
373
377
|
Send
|
|
374
378
|
</button>
|
|
@@ -1,174 +1,174 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import { ComputedRef, PropType, computed, onMounted, ref } from 'vue';
|
|
3
|
-
import {
|
|
4
|
-
getActiveValidators,
|
|
5
|
-
getInactiveValidators,
|
|
6
|
-
getStakingParam,
|
|
7
|
-
} from '../../../utils/http';
|
|
8
|
-
import { decimal2percent } from '../../../utils/format';
|
|
9
|
-
import { Coin, CoinMetadata } from '../../../utils/type';
|
|
10
|
-
import { TokenUnitConverter } from '../../../utils/TokenUnitConverter';
|
|
11
|
-
|
|
12
|
-
const props = defineProps({
|
|
13
|
-
endpoint: { type: String, required: true },
|
|
14
|
-
sender: { type: String, required: true },
|
|
15
|
-
balances: Object as PropType<Coin[]>,
|
|
16
|
-
metadata: Object as PropType<Record<string, CoinMetadata>>,
|
|
17
|
-
params: String,
|
|
18
|
-
});
|
|
19
|
-
const params = computed(() => JSON.parse(props.params || '{}'));
|
|
20
|
-
|
|
21
|
-
const validator = ref('');
|
|
22
|
-
|
|
23
|
-
const activeValidators = ref([]);
|
|
24
|
-
const inactiveValidators = ref([]);
|
|
25
|
-
const stakingDenom = ref('');
|
|
26
|
-
const unbondingTime = ref('');
|
|
27
|
-
const amount = ref('');
|
|
28
|
-
const amountDenom = ref('');
|
|
29
|
-
|
|
30
|
-
const msgs = computed(() => {
|
|
31
|
-
const convert = new TokenUnitConverter(props.metadata);
|
|
32
|
-
return [
|
|
33
|
-
{
|
|
34
|
-
typeUrl: '/cosmos.staking.v1beta1.MsgDelegate',
|
|
35
|
-
value: {
|
|
36
|
-
delegatorAddress: props.sender,
|
|
37
|
-
validatorAddress: validator.value,
|
|
38
|
-
amount: convert.displayToBase(stakingDenom.value, {
|
|
39
|
-
amount: String(amount.value),
|
|
40
|
-
denom: amountDenom.value,
|
|
41
|
-
}),
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
];
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const list: ComputedRef<
|
|
48
|
-
{
|
|
49
|
-
operator_address: string;
|
|
50
|
-
description: { moniker: string };
|
|
51
|
-
commission: { commission_rates: { rate: string } };
|
|
52
|
-
status: string;
|
|
53
|
-
}[]
|
|
54
|
-
> = computed(() => {
|
|
55
|
-
return [...activeValidators.value, ...inactiveValidators.value];
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const available = computed(() => {
|
|
59
|
-
const convert = new TokenUnitConverter(props.metadata);
|
|
60
|
-
const base = props.balances?.find(
|
|
61
|
-
(x) => x.denom === stakingDenom.value
|
|
62
|
-
) || { amount: '0', denom: stakingDenom.value };
|
|
63
|
-
return {
|
|
64
|
-
base,
|
|
65
|
-
display: convert.baseToUnit(base, amountDenom.value),
|
|
66
|
-
};
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
function loadInactiveValidators() {
|
|
70
|
-
getInactiveValidators(props.endpoint).then((x) => {
|
|
71
|
-
inactiveValidators.value = x.validators;
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const units = computed(() => {
|
|
76
|
-
if (!props.metadata || !props.metadata[stakingDenom.value]) {
|
|
77
|
-
amountDenom.value = stakingDenom.value;
|
|
78
|
-
return [{ denom: stakingDenom.value, exponent: 0, aliases: [] }];
|
|
79
|
-
}
|
|
80
|
-
const list = props.metadata[stakingDenom.value].denom_units.sort(
|
|
81
|
-
(a, b) => b.exponent - a.exponent
|
|
82
|
-
);
|
|
83
|
-
if (list.length > 0) amountDenom.value = list[0].denom;
|
|
84
|
-
return list;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const isValid = computed(() => {
|
|
88
|
-
let ok = true;
|
|
89
|
-
let error = '';
|
|
90
|
-
if (!validator.value) {
|
|
91
|
-
ok = false;
|
|
92
|
-
error = 'Validator is empty';
|
|
93
|
-
}
|
|
94
|
-
if (!(Number(amount.value) > 0)) {
|
|
95
|
-
ok = false;
|
|
96
|
-
error = 'Amount should be great than 0';
|
|
97
|
-
}
|
|
98
|
-
if (!amountDenom.value) {
|
|
99
|
-
ok = false;
|
|
100
|
-
error = 'Amount Denom is empty';
|
|
101
|
-
}
|
|
102
|
-
return { ok, error };
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
function initial() {
|
|
106
|
-
activeValidators.value = [];
|
|
107
|
-
validator.value = params.value.validator_address;
|
|
108
|
-
getStakingParam(props.endpoint).then((x) => {
|
|
109
|
-
stakingDenom.value = x.params.bond_denom;
|
|
110
|
-
unbondingTime.value = x.params.unbonding_time;
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
getActiveValidators(props.endpoint).then((x) => {
|
|
114
|
-
activeValidators.value = x.validators;
|
|
115
|
-
if (!params.value.validator_address) {
|
|
116
|
-
validator.value = x.validators.find(
|
|
117
|
-
(v) => v.description.identity === '6783E9F948541962'
|
|
118
|
-
)?.operator_address;
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
defineExpose({ msgs, isValid, initial });
|
|
124
|
-
</script>
|
|
125
|
-
<template>
|
|
126
|
-
<div>
|
|
127
|
-
<div class="form-control">
|
|
128
|
-
<label class="label">
|
|
129
|
-
<span class="label-text">Sender</span>
|
|
130
|
-
</label>
|
|
131
|
-
<input
|
|
132
|
-
:value="sender"
|
|
133
|
-
type="text"
|
|
134
|
-
class="text-gray-600 dark:text-white input border !border-gray-300 dark:!border-
|
|
135
|
-
/>
|
|
136
|
-
</div>
|
|
137
|
-
<div class="form-control">
|
|
138
|
-
<label class="label">
|
|
139
|
-
<span class="label-text">Validator</span>
|
|
140
|
-
<a class="label-text" @click="loadInactiveValidators()"
|
|
141
|
-
>Show Inactive</a
|
|
142
|
-
>
|
|
143
|
-
</label>
|
|
144
|
-
<select v-model="validator" class="select select-bordered dark:border-
|
|
145
|
-
<option value="">Select a validator</option>
|
|
146
|
-
<option v-for="v in list" :value="v.operator_address">
|
|
147
|
-
{{ v.description.moniker }} ({{
|
|
148
|
-
decimal2percent(v.commission.commission_rates.rate)
|
|
149
|
-
}}%)
|
|
150
|
-
<span v-if="v.status !== 'BOND_STATUS_BONDED'">x</span>
|
|
151
|
-
</option>
|
|
152
|
-
</select>
|
|
153
|
-
</div>
|
|
154
|
-
<div class="form-control">
|
|
155
|
-
<label class="label">
|
|
156
|
-
<span class="label-text">Amount</span>
|
|
157
|
-
<span>
|
|
158
|
-
{{ available?.display.amount }} {{ available?.display.denom }}
|
|
159
|
-
</span>
|
|
160
|
-
</label>
|
|
161
|
-
<label class="join">
|
|
162
|
-
<input
|
|
163
|
-
v-model="amount"
|
|
164
|
-
type="number"
|
|
165
|
-
:placeholder="`Available: ${available?.display.amount}`"
|
|
166
|
-
class="input border border-gray-300 dark:border-
|
|
167
|
-
/>
|
|
168
|
-
<select v-model="amountDenom" class="select select-bordered join-item dark:border-
|
|
169
|
-
<option v-for="u in units">{{ u.denom }}</option>
|
|
170
|
-
</select>
|
|
171
|
-
</label>
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
</template>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ComputedRef, PropType, computed, onMounted, ref } from 'vue';
|
|
3
|
+
import {
|
|
4
|
+
getActiveValidators,
|
|
5
|
+
getInactiveValidators,
|
|
6
|
+
getStakingParam,
|
|
7
|
+
} from '../../../utils/http';
|
|
8
|
+
import { decimal2percent } from '../../../utils/format';
|
|
9
|
+
import { Coin, CoinMetadata } from '../../../utils/type';
|
|
10
|
+
import { TokenUnitConverter } from '../../../utils/TokenUnitConverter';
|
|
11
|
+
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
endpoint: { type: String, required: true },
|
|
14
|
+
sender: { type: String, required: true },
|
|
15
|
+
balances: Object as PropType<Coin[]>,
|
|
16
|
+
metadata: Object as PropType<Record<string, CoinMetadata>>,
|
|
17
|
+
params: String,
|
|
18
|
+
});
|
|
19
|
+
const params = computed(() => JSON.parse(props.params || '{}'));
|
|
20
|
+
|
|
21
|
+
const validator = ref('');
|
|
22
|
+
|
|
23
|
+
const activeValidators = ref([]);
|
|
24
|
+
const inactiveValidators = ref([]);
|
|
25
|
+
const stakingDenom = ref('');
|
|
26
|
+
const unbondingTime = ref('');
|
|
27
|
+
const amount = ref('');
|
|
28
|
+
const amountDenom = ref('');
|
|
29
|
+
|
|
30
|
+
const msgs = computed(() => {
|
|
31
|
+
const convert = new TokenUnitConverter(props.metadata);
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
typeUrl: '/cosmos.staking.v1beta1.MsgDelegate',
|
|
35
|
+
value: {
|
|
36
|
+
delegatorAddress: props.sender,
|
|
37
|
+
validatorAddress: validator.value,
|
|
38
|
+
amount: convert.displayToBase(stakingDenom.value, {
|
|
39
|
+
amount: String(amount.value),
|
|
40
|
+
denom: amountDenom.value,
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const list: ComputedRef<
|
|
48
|
+
{
|
|
49
|
+
operator_address: string;
|
|
50
|
+
description: { moniker: string };
|
|
51
|
+
commission: { commission_rates: { rate: string } };
|
|
52
|
+
status: string;
|
|
53
|
+
}[]
|
|
54
|
+
> = computed(() => {
|
|
55
|
+
return [...activeValidators.value, ...inactiveValidators.value];
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const available = computed(() => {
|
|
59
|
+
const convert = new TokenUnitConverter(props.metadata);
|
|
60
|
+
const base = props.balances?.find(
|
|
61
|
+
(x) => x.denom === stakingDenom.value
|
|
62
|
+
) || { amount: '0', denom: stakingDenom.value };
|
|
63
|
+
return {
|
|
64
|
+
base,
|
|
65
|
+
display: convert.baseToUnit(base, amountDenom.value),
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
function loadInactiveValidators() {
|
|
70
|
+
getInactiveValidators(props.endpoint).then((x) => {
|
|
71
|
+
inactiveValidators.value = x.validators;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const units = computed(() => {
|
|
76
|
+
if (!props.metadata || !props.metadata[stakingDenom.value]) {
|
|
77
|
+
amountDenom.value = stakingDenom.value;
|
|
78
|
+
return [{ denom: stakingDenom.value, exponent: 0, aliases: [] }];
|
|
79
|
+
}
|
|
80
|
+
const list = props.metadata[stakingDenom.value].denom_units.sort(
|
|
81
|
+
(a, b) => b.exponent - a.exponent
|
|
82
|
+
);
|
|
83
|
+
if (list.length > 0) amountDenom.value = list[0].denom;
|
|
84
|
+
return list;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const isValid = computed(() => {
|
|
88
|
+
let ok = true;
|
|
89
|
+
let error = '';
|
|
90
|
+
if (!validator.value) {
|
|
91
|
+
ok = false;
|
|
92
|
+
error = 'Validator is empty';
|
|
93
|
+
}
|
|
94
|
+
if (!(Number(amount.value) > 0)) {
|
|
95
|
+
ok = false;
|
|
96
|
+
error = 'Amount should be great than 0';
|
|
97
|
+
}
|
|
98
|
+
if (!amountDenom.value) {
|
|
99
|
+
ok = false;
|
|
100
|
+
error = 'Amount Denom is empty';
|
|
101
|
+
}
|
|
102
|
+
return { ok, error };
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
function initial() {
|
|
106
|
+
activeValidators.value = [];
|
|
107
|
+
validator.value = params.value.validator_address;
|
|
108
|
+
getStakingParam(props.endpoint).then((x) => {
|
|
109
|
+
stakingDenom.value = x.params.bond_denom;
|
|
110
|
+
unbondingTime.value = x.params.unbonding_time;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
getActiveValidators(props.endpoint).then((x) => {
|
|
114
|
+
activeValidators.value = x.validators;
|
|
115
|
+
if (!params.value.validator_address) {
|
|
116
|
+
validator.value = x.validators.find(
|
|
117
|
+
(v) => v.description.identity === '6783E9F948541962'
|
|
118
|
+
)?.operator_address;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
defineExpose({ msgs, isValid, initial });
|
|
124
|
+
</script>
|
|
125
|
+
<template>
|
|
126
|
+
<div>
|
|
127
|
+
<div class="form-control">
|
|
128
|
+
<label class="label">
|
|
129
|
+
<span class="label-text">Sender</span>
|
|
130
|
+
</label>
|
|
131
|
+
<input
|
|
132
|
+
:value="sender"
|
|
133
|
+
type="text"
|
|
134
|
+
class="text-gray-600 dark:text-white input border !border-gray-300 dark:!border-neutral-700"
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
<div class="form-control">
|
|
138
|
+
<label class="label">
|
|
139
|
+
<span class="label-text">Validator</span>
|
|
140
|
+
<a class="label-text" @click="loadInactiveValidators()"
|
|
141
|
+
>Show Inactive</a
|
|
142
|
+
>
|
|
143
|
+
</label>
|
|
144
|
+
<select v-model="validator" class="select select-bordered dark:border-neutral-700 dark:text-white">
|
|
145
|
+
<option value="">Select a validator</option>
|
|
146
|
+
<option v-for="v in list" :value="v.operator_address">
|
|
147
|
+
{{ v.description.moniker }} ({{
|
|
148
|
+
decimal2percent(v.commission.commission_rates.rate)
|
|
149
|
+
}}%)
|
|
150
|
+
<span v-if="v.status !== 'BOND_STATUS_BONDED'">x</span>
|
|
151
|
+
</option>
|
|
152
|
+
</select>
|
|
153
|
+
</div>
|
|
154
|
+
<div class="form-control">
|
|
155
|
+
<label class="label">
|
|
156
|
+
<span class="label-text">Amount</span>
|
|
157
|
+
<span>
|
|
158
|
+
{{ available?.display.amount }} {{ available?.display.denom }}
|
|
159
|
+
</span>
|
|
160
|
+
</label>
|
|
161
|
+
<label class="join">
|
|
162
|
+
<input
|
|
163
|
+
v-model="amount"
|
|
164
|
+
type="number"
|
|
165
|
+
:placeholder="`Available: ${available?.display.amount}`"
|
|
166
|
+
class="input border border-gray-300 dark:border-neutral-700 w-full join-item dark:text-white"
|
|
167
|
+
/>
|
|
168
|
+
<select v-model="amountDenom" class="select select-bordered join-item dark:border-neutral-700 dark:text-white">
|
|
169
|
+
<option v-for="u in units">{{ u.denom }}</option>
|
|
170
|
+
</select>
|
|
171
|
+
</label>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</template>
|