mirror of
https://github.com/Instadapp/assembly.git
synced 2024-07-29 22:37:06 +00:00
closes #10
This commit is contained in:
parent
131bc04455
commit
0ad579c6e7
|
@ -31,7 +31,7 @@
|
||||||
<toggle-button
|
<toggle-button
|
||||||
v-if="active && canSimulate"
|
v-if="active && canSimulate"
|
||||||
@change="checked => (checked ? startSimulation() : stopSimulation())"
|
@change="checked => (checked ? startSimulation() : stopSimulation())"
|
||||||
:checked="forkId"
|
:checked="!! forkId"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
class="ml-4 border-l pl-4"
|
class="ml-4 border-l pl-4"
|
||||||
label="Simulation Mode"
|
label="Simulation Mode"
|
||||||
|
|
41
components/common/input/ButtonCTAOutlined.vue
Normal file
41
components/common/input/ButtonCTAOutlined.vue
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<button
|
||||||
|
class="flex items-center justify-center flex-shrink-0 py-2 font-semibold whitespace-no-wrap duration-75 ease-out transform rounded-[4px] select-none border border-ocean-blue-pure text-ocean-blue-pure shadow-cta focus:outline-none dark:shadow-none"
|
||||||
|
:class="{
|
||||||
|
'bg-opacity-50 pointer-events-none': disabled && !loading,
|
||||||
|
'hover:-translate-y-px': !disabled && !loading,
|
||||||
|
'active:translate-y-px': !disabled && !loading
|
||||||
|
}"
|
||||||
|
:disabled="disabled || loading"
|
||||||
|
v-bind="$attrs"
|
||||||
|
v-on="$listeners"
|
||||||
|
>
|
||||||
|
<slot v-if="!loading" />
|
||||||
|
<CustomTransition
|
||||||
|
enter-active-class="duration-200 ease-out"
|
||||||
|
enter-class="w-0 ml-0 opacity-0"
|
||||||
|
enter-to-class="w-4 opacity-100"
|
||||||
|
after-enter-class="w-4 "
|
||||||
|
leave-active-class="duration-100 ease-in"
|
||||||
|
leave-class="w-4 opacity-100"
|
||||||
|
leave-to-class="w-0 ml-0 opacity-0"
|
||||||
|
>
|
||||||
|
<SVGSpinner v-if="loading" class="h-4 animate-spin-loading" />
|
||||||
|
</CustomTransition>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from '@nuxtjs/composition-api'
|
||||||
|
import SVGSpinner from '@/assets/icons/spinner.svg?inline'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
SVGSpinner,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
loading: { type: Boolean, default: false },
|
||||||
|
disabled: { type: Boolean, default: false },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
74
components/modal/authority/AddAuthorityDialog.vue
Normal file
74
components/modal/authority/AddAuthorityDialog.vue
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="inline-block w-full max-w-md px-8 py-7 overflow-hidden text-left align-bottom transition-all transform bg-white border border-opacity-50 rounded-lg shadow-xl dark:bg-dark-400 sm:my-8 sm:align-middle sm:p-6 border-green-light"
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-labelledby="modal-headline"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div class="mt-3 text-center sm:mt-5">
|
||||||
|
<h3 id="modal-headline" class="font-bold text-2xl">
|
||||||
|
Add Authority
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="my-10">
|
||||||
|
<div class="relative">
|
||||||
|
<Input class="mr-4" v-model="authority" />
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-if="!authority"
|
||||||
|
class="absolute right-0 inset-y-0 mt-3 mr-4 uppercase text-[#1874FF] font-semibold text-xs"
|
||||||
|
>Paste</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center mt-4 sm:mt-6">
|
||||||
|
<ButtonCTAOutlined class="flex-1 px-8 rounded" @click="close">
|
||||||
|
Cancel
|
||||||
|
</ButtonCTAOutlined>
|
||||||
|
|
||||||
|
<ButtonCTA
|
||||||
|
@click="createAuthorityHandler"
|
||||||
|
class="ml-4 flex-1 px-8"
|
||||||
|
:loading="creatingAuthority"
|
||||||
|
:disabled="creatingAuthority"
|
||||||
|
>
|
||||||
|
create
|
||||||
|
</ButtonCTA>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, ref } from '@nuxtjs/composition-api'
|
||||||
|
import Input from '~/components/common/input/Input.vue'
|
||||||
|
import { useDSA } from '~/composables/useDSA'
|
||||||
|
import { useModal } from '~/composables/useModal'
|
||||||
|
import ButtonCTA from '../../common/input/ButtonCTA.vue'
|
||||||
|
import ButtonCTAOutlined from '../../common/input/ButtonCTAOutlined.vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: { ButtonCTA, ButtonCTAOutlined, Input },
|
||||||
|
setup() {
|
||||||
|
const { close } = useModal()
|
||||||
|
const { createAuthority, creatingAuthority } = useDSA()
|
||||||
|
|
||||||
|
const authority = ref();
|
||||||
|
|
||||||
|
const createAuthorityHandler = async () => {
|
||||||
|
await createAuthority(authority.value)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
authority,
|
||||||
|
close,
|
||||||
|
createAuthorityHandler,
|
||||||
|
creatingAuthority,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
89
components/modal/authority/RemoveAuthorityDialog.vue
Normal file
89
components/modal/authority/RemoveAuthorityDialog.vue
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="inline-block w-full max-w-md px-4 py-6 overflow-hidden text-left align-bottom transition-all transform bg-white border border-opacity-50 rounded-lg shadow-xl dark:bg-dark-400 sm:my-8 sm:align-middle sm:p-6 border-green-light"
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-labelledby="modal-headline"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div class="mt-3 text-center sm:mt-5">
|
||||||
|
<h3 id="modal-headline" class="font-bold text-2xl">
|
||||||
|
Remove Authority
|
||||||
|
</h3>
|
||||||
|
<p class="px-6 mt-4 text-[#9FB0C9]">
|
||||||
|
this action will remove this account as authority
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="border-b border-[#DBE5F4] py-4 text-sm text-center flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="mr-2"
|
||||||
|
width="12"
|
||||||
|
height="14"
|
||||||
|
viewBox="0 0 12 14"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M6 7C7.89375 7 9.42857 5.4332 9.42857 3.5C9.42857 1.5668 7.89375 0 6 0C4.10625 0 2.57143 1.5668 2.57143 3.5C2.57143 5.4332 4.10625 7 6 7ZM8.56607 7.89141L7.28571 13.125L6.42857 9.40625L7.28571 7.875H4.71429L5.57143 9.40625L4.71429 13.125L3.43393 7.89141C1.52411 7.98438 0 9.57852 0 11.55V12.6875C0 13.4121 0.575893 14 1.28571 14H10.7143C11.4241 14 12 13.4121 12 12.6875V11.55C12 9.57852 10.4759 7.98438 8.56607 7.89141Z"
|
||||||
|
fill="#9FB0C9"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ authority }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center mt-4 sm:mt-6">
|
||||||
|
<ButtonCTAOutlined class="flex-1 px-8 rounded" @click="close">
|
||||||
|
Cancel
|
||||||
|
</ButtonCTAOutlined>
|
||||||
|
|
||||||
|
<ButtonCTA
|
||||||
|
@click="removeAuthorityHandler(authority)"
|
||||||
|
class="ml-4 flex-1 px-8"
|
||||||
|
:loading="removingAuthority"
|
||||||
|
:disabled="removingAuthority"
|
||||||
|
>
|
||||||
|
Remove
|
||||||
|
</ButtonCTA>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from '@nuxtjs/composition-api'
|
||||||
|
import { useDSA } from '~/composables/useDSA'
|
||||||
|
import { useModal } from '~/composables/useModal'
|
||||||
|
import ButtonCTA from '../../common/input/ButtonCTA.vue'
|
||||||
|
import ButtonCTAOutlined from '../../common/input/ButtonCTAOutlined.vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
authority: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: { ButtonCTA, ButtonCTAOutlined },
|
||||||
|
setup() {
|
||||||
|
const { close } = useModal()
|
||||||
|
const { removeAuthority, removingAuthority } = useDSA()
|
||||||
|
|
||||||
|
const removeAuthorityHandler = async (authority) => {
|
||||||
|
await removeAuthority(authority)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
close,
|
||||||
|
removeAuthorityHandler,
|
||||||
|
removingAuthority,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -45,6 +45,7 @@ export function useBalances() {
|
||||||
});
|
});
|
||||||
const fetchBalances = async (refresh = false) => {
|
const fetchBalances = async (refresh = false) => {
|
||||||
if (!balances.user || refresh) {
|
if (!balances.user || refresh) {
|
||||||
|
if (!account.value) return;
|
||||||
balances.user = {
|
balances.user = {
|
||||||
mainnet:
|
mainnet:
|
||||||
networkName.value === Network.Mainnet
|
networkName.value === Network.Mainnet
|
||||||
|
@ -58,6 +59,8 @@ export function useBalances() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!balances.dsa || refresh) {
|
if (!balances.dsa || refresh) {
|
||||||
|
if (!activeAccount.value) return;
|
||||||
|
|
||||||
balances.dsa = {
|
balances.dsa = {
|
||||||
mainnet:
|
mainnet:
|
||||||
networkName.value === Network.Mainnet
|
networkName.value === Network.Mainnet
|
||||||
|
@ -123,8 +126,6 @@ export function useBalances() {
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(web3, () => {
|
watch(web3, () => {
|
||||||
console.log("Fetch balances");
|
|
||||||
|
|
||||||
fetchBalances(true);
|
fetchBalances(true);
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
@ -144,8 +145,6 @@ async function getBalances(
|
||||||
web3: Web3,
|
web3: Web3,
|
||||||
additionalTokens = []
|
additionalTokens = []
|
||||||
) {
|
) {
|
||||||
console.log("getBalances", owner, network, web3);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const tokenResolverABI = abis.resolver.balance;
|
const tokenResolverABI = abis.resolver.balance;
|
||||||
const tokenResolverAddr = addresses[network].resolver.balance;
|
const tokenResolverAddr = addresses[network].resolver.balance;
|
||||||
|
|
|
@ -2,58 +2,63 @@ import { computed, readonly, ref, watch } from "@nuxtjs/composition-api";
|
||||||
import { useWeb3 } from "./useWeb3";
|
import { useWeb3 } from "./useWeb3";
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import DSA from "dsa-connect";
|
import DSA from "dsa-connect";
|
||||||
|
import addresses from "~/constant/addresses";
|
||||||
|
import abis from "~/constant/abis";
|
||||||
|
import { AbiItem } from "web3-utils";
|
||||||
|
import { useNotification } from "./useNotification";
|
||||||
|
|
||||||
const dsa = ref<DSA>();
|
const dsa = ref<DSA>();
|
||||||
const accounts = ref<any[]>([]);
|
const accounts = ref<any[]>([]);
|
||||||
const activeAccount = ref<any>();
|
const activeAccount = ref<any>();
|
||||||
|
const authorities = ref<string[]>();
|
||||||
|
|
||||||
export function useDSA() {
|
export function useDSA() {
|
||||||
const { web3, chainId } = useWeb3();
|
const { web3, chainId, networkName, account } = useWeb3();
|
||||||
|
const { showWarning } = useNotification();
|
||||||
|
|
||||||
watch(
|
watch(web3, () => {
|
||||||
web3,
|
|
||||||
() => {
|
|
||||||
if (web3.value) {
|
if (web3.value) {
|
||||||
dsa.value = new DSA(web3.value, chainId.value);
|
dsa.value = new DSA(web3.value, chainId.value);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(chainId, () => {
|
||||||
chainId,
|
|
||||||
() => {
|
|
||||||
if (web3.value) {
|
if (web3.value) {
|
||||||
dsa.value = new DSA(web3.value, chainId.value);
|
dsa.value = new DSA(web3.value, chainId.value);
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(dsa, async () => {
|
||||||
dsa,
|
|
||||||
async () => {
|
|
||||||
if (dsa.value) {
|
if (dsa.value) {
|
||||||
accounts.value = await dsa.value.getAccounts();
|
accounts.value = await dsa.value.getAccounts();
|
||||||
|
|
||||||
if (accounts.value.length > 0) {
|
if (accounts.value.length > 0) {
|
||||||
activeAccount.value = accounts.value[0];
|
activeAccount.value = accounts.value[0];
|
||||||
|
} else {
|
||||||
|
activeAccount.value = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
window.dsa = dsa.value
|
window.dsa = dsa.value;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
activeAccount,
|
activeAccount,
|
||||||
async () => {
|
async () => {
|
||||||
|
authorities.value = [];
|
||||||
|
|
||||||
if (activeAccount.value) {
|
if (activeAccount.value) {
|
||||||
dsa.value.setAccount(activeAccount.value.id);
|
dsa.value.setAccount(activeAccount.value.id);
|
||||||
|
|
||||||
|
fethAuthorities();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const creatingAccount = ref(false);
|
const creatingAccount = ref(false);
|
||||||
|
const creatingAuthority = ref(false);
|
||||||
|
const removingAuthority = ref(false);
|
||||||
|
|
||||||
async function createAccount() {
|
async function createAccount() {
|
||||||
creatingAccount.value = true;
|
creatingAccount.value = true;
|
||||||
|
@ -72,6 +77,88 @@ export function useDSA() {
|
||||||
activeAccount.value = account;
|
activeAccount.value = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fethAuthorities() {
|
||||||
|
try {
|
||||||
|
const accountsResolverInstance = new web3.value.eth.Contract(
|
||||||
|
abis.resolver.accounts as AbiItem[],
|
||||||
|
addresses[networkName.value].resolver.accounts
|
||||||
|
);
|
||||||
|
const rawData = await accountsResolverInstance.methods
|
||||||
|
.getAccountAuthorities(activeAccount.value.address)
|
||||||
|
.call();
|
||||||
|
|
||||||
|
authorities.value = rawData;
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createAuthority(newAuthority: string) {
|
||||||
|
try {
|
||||||
|
if (!newAuthority) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const owners = authorities.value.map(x => x.toLowerCase());
|
||||||
|
|
||||||
|
if (owners.includes(newAuthority.toLowerCase())) {
|
||||||
|
showWarning("Create Authority", "Account is already an owner!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
creatingAuthority.value = true;
|
||||||
|
|
||||||
|
const spells = dsa.value.Spell();
|
||||||
|
|
||||||
|
spells.add({
|
||||||
|
connector: "authority",
|
||||||
|
method: "add",
|
||||||
|
args: [newAuthority]
|
||||||
|
});
|
||||||
|
|
||||||
|
const transactionHash = await dsa.value.cast({
|
||||||
|
spells,
|
||||||
|
from: account.value
|
||||||
|
});
|
||||||
|
|
||||||
|
creatingAuthority.value = false;
|
||||||
|
|
||||||
|
fethAuthorities();
|
||||||
|
|
||||||
|
return transactionHash;
|
||||||
|
} catch (error) {
|
||||||
|
creatingAuthority.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeAuthority(authority) {
|
||||||
|
try {
|
||||||
|
if (authorities.value.length <= 1) {
|
||||||
|
showWarning("Remove Authority", "Cannot remove all authorities!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removingAuthority.value = true;
|
||||||
|
|
||||||
|
const spells = dsa.value.Spell();
|
||||||
|
|
||||||
|
spells.add({
|
||||||
|
connector: "authority",
|
||||||
|
method: "remove",
|
||||||
|
args: [authority]
|
||||||
|
});
|
||||||
|
|
||||||
|
const transactionHash = await dsa.value.cast({
|
||||||
|
spells,
|
||||||
|
from: account.value
|
||||||
|
});
|
||||||
|
|
||||||
|
removingAuthority.value = false;
|
||||||
|
|
||||||
|
fethAuthorities();
|
||||||
|
|
||||||
|
return transactionHash;
|
||||||
|
} catch (error) {
|
||||||
|
removingAuthority.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dsa,
|
dsa,
|
||||||
activeAccount: readonly(activeAccount),
|
activeAccount: readonly(activeAccount),
|
||||||
|
@ -80,6 +167,11 @@ export function useDSA() {
|
||||||
creatingAccount,
|
creatingAccount,
|
||||||
setAccount,
|
setAccount,
|
||||||
web3,
|
web3,
|
||||||
chainId
|
chainId,
|
||||||
|
authorities,
|
||||||
|
createAuthority,
|
||||||
|
creatingAuthority,
|
||||||
|
removeAuthority,
|
||||||
|
removingAuthority
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,14 +107,14 @@ export function useFormatting() {
|
||||||
return formatter.format(value);
|
return formatter.format(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shortenHash(hash: any) {
|
function shortenHash(hash: any, size = 4) {
|
||||||
if (!hash) return;
|
if (!hash) return;
|
||||||
|
|
||||||
if (hash.length < 12) return hash;
|
if (hash.length < 12) return hash;
|
||||||
|
|
||||||
const beginningChars = hash.startsWith("0x") ? 6 : 4;
|
const beginningChars = hash.startsWith("0x") ? size + 2 : size;
|
||||||
|
|
||||||
const shortened = hash.substr(0, beginningChars) + "…" + hash.substr(-4);
|
const shortened = hash.substr(0, beginningChars) + "…" + hash.substr(-size);
|
||||||
|
|
||||||
return shortened;
|
return shortened;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,18 @@ export function useModal() {
|
||||||
|
|
||||||
const isShown = computed(() => !!modal.value);
|
const isShown = computed(() => !!modal.value);
|
||||||
|
|
||||||
|
function showComponent(component, componentProps = {}) {
|
||||||
|
modal.value = component;
|
||||||
|
props.value = componentProps;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
showNetworksMismatchDialog,
|
showNetworksMismatchDialog,
|
||||||
close,
|
close,
|
||||||
closePersistent,
|
closePersistent,
|
||||||
isShown,
|
isShown,
|
||||||
modal: computed(() => modal.value),
|
modal: computed(() => modal.value),
|
||||||
props: computed(() => props.value)
|
props: computed(() => props.value),
|
||||||
|
showComponent
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
<NotificationBar />
|
<NotificationBar />
|
||||||
|
|
||||||
<div class="fixed bottom-0 right-0 mr-10 mb-40">
|
<div class="fixed bottom-0 right-0 mr-10 mb-28">
|
||||||
<button
|
<button
|
||||||
@click="showSidebarBalances"
|
@click="showSidebarBalances"
|
||||||
class="px-9 h-[56px] bg-primary-blue-dark hover:bg-primary-blue-hover text-white rounded-[28px] text-lg font-semibold shadow flex items-center"
|
class="px-9 h-[56px] bg-primary-blue-dark hover:bg-primary-blue-hover text-white rounded-[28px] text-lg font-semibold shadow flex items-center"
|
||||||
|
|
|
@ -55,14 +55,16 @@
|
||||||
<div class="text-semibold text-sm text-grey-dark uppercase">
|
<div class="text-semibold text-sm text-grey-dark uppercase">
|
||||||
#{{ activeAccount.id }}
|
#{{ activeAccount.id }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="false" class="mt-3 text-2xl font-semibold">Account Name</div>
|
<div class="hidden mt-3 text-2xl font-semibold">Account Name</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="font-medium text-lg">
|
<div class="font-medium text-lg">
|
||||||
Account address
|
Account address
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 text-lg font-medium text-grey-dark flex items-center">
|
<div
|
||||||
|
class="mt-4 text-lg font-medium text-grey-dark flex items-center"
|
||||||
|
>
|
||||||
{{ activeAccount.address }}
|
{{ activeAccount.address }}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -101,43 +103,108 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-12 hidden">
|
<div class="mt-12">
|
||||||
<h3 class="text-semibold text-sm text-primary-gray-dark uppercase">
|
<div class="flex justify-between items-center">
|
||||||
|
<h3 class="text-semibold text-sm text-primary-gray uppercase">
|
||||||
Authorities
|
Authorities
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
<ButtonCTA @click="addAuthority" class="h-8 w-52 text-xs uppercase font-semibold">
|
||||||
|
Add authority
|
||||||
|
</ButtonCTA>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="mt-4 p-8 border border-[#DBE5F4] rounded-[2px] grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-6"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="authority in authorities"
|
||||||
|
:key="authority"
|
||||||
|
class="border border-[#DBE5F4] text-[#9FB0C9] rounded-[2px] flex items-center px-6 py-7"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<svg
|
||||||
|
width="16"
|
||||||
|
height="18"
|
||||||
|
viewBox="0 0 16 18"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8 9C10.525 9 12.5714 6.98555 12.5714 4.5C12.5714 2.01445 10.525 0 8 0C5.475 0 3.42857 2.01445 3.42857 4.5C3.42857 6.98555 5.475 9 8 9ZM11.4214 10.1461L9.71429 16.875L8.57143 12.0938L9.71429 10.125H6.28571L7.42857 12.0938L6.28571 16.875L4.57857 10.1461C2.03214 10.2656 0 12.3152 0 14.85V16.3125C0 17.2441 0.767857 18 1.71429 18H14.2857C15.2321 18 16 17.2441 16 16.3125V14.85C16 12.3152 13.9679 10.2656 11.4214 10.1461Z"
|
||||||
|
fill="#9FB0C9"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
:href="`${addressDetailsLink}/${authority}`"
|
||||||
|
target="_blank"
|
||||||
|
class="hover:underline flex-1 text-center font-medium text-lg text-primary-black truncate px-4"
|
||||||
|
>
|
||||||
|
{{ shortenHash(authority, 16) }}
|
||||||
|
</a>
|
||||||
|
<button @click="deleteAuthority(authority)">
|
||||||
|
<Icon name="trash" class="w-5"></Icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, watch } from "@nuxtjs/composition-api";
|
import { defineComponent, watch } from "@nuxtjs/composition-api";
|
||||||
|
import ButtonCTA from "~/components/common/input/ButtonCTA.vue";
|
||||||
|
import RemoveAuthorityDialog from "~/components/modal/authority/RemoveAuthorityDialog.vue";
|
||||||
|
import AddAuthorityDialog from "~/components/modal/authority/AddAuthorityDialog.vue";
|
||||||
import { useBalances } from "~/composables/useBalances";
|
import { useBalances } from "~/composables/useBalances";
|
||||||
import { useCopiedToClipboardUx } from "~/composables/useCopiedToClipboardUx";
|
import { useCopiedToClipboardUx } from "~/composables/useCopiedToClipboardUx";
|
||||||
import { useDSA } from "~/composables/useDSA";
|
import { useDSA } from "~/composables/useDSA";
|
||||||
|
import { useFormatting } from "~/composables/useFormatting";
|
||||||
|
import { useLink } from "~/composables/useLink";
|
||||||
|
import { useModal } from "~/composables/useModal";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {},
|
components: { ButtonCTA },
|
||||||
setup() {
|
setup() {
|
||||||
const {
|
const {
|
||||||
accounts,
|
accounts,
|
||||||
activeAccount,
|
activeAccount,
|
||||||
setAccount,
|
setAccount,
|
||||||
createAccount,
|
createAccount,
|
||||||
creatingAccount
|
creatingAccount,
|
||||||
|
authorities
|
||||||
} = useDSA();
|
} = useDSA();
|
||||||
|
const { shortenHash } = useFormatting();
|
||||||
const { fetchBalances } = useBalances();
|
const { fetchBalances } = useBalances();
|
||||||
const { onCopy, tooltip, copied } = useCopiedToClipboardUx();
|
const { onCopy, tooltip, copied } = useCopiedToClipboardUx();
|
||||||
|
const { addressDetailsLink } = useLink();
|
||||||
|
const { showComponent } = useModal();
|
||||||
|
|
||||||
watch(activeAccount, val => val && fetchBalances(true));
|
watch(activeAccount, val => val && fetchBalances(true));
|
||||||
|
|
||||||
|
const deleteAuthority = (authority: string) => {
|
||||||
|
showComponent(RemoveAuthorityDialog, { authority });
|
||||||
|
};
|
||||||
|
|
||||||
|
const addAuthority = () => {
|
||||||
|
showComponent(AddAuthorityDialog);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
addressDetailsLink,
|
||||||
|
shortenHash,
|
||||||
accounts,
|
accounts,
|
||||||
activeAccount,
|
activeAccount,
|
||||||
setAccount,
|
setAccount,
|
||||||
createAccount,
|
createAccount,
|
||||||
creatingAccount,
|
creatingAccount,
|
||||||
|
authorities,
|
||||||
onCopy,
|
onCopy,
|
||||||
tooltip,
|
tooltip,
|
||||||
copied
|
copied,
|
||||||
|
deleteAuthority,
|
||||||
|
addAuthority,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user