Skip to content

Commit

Permalink
add proposal details types
Browse files Browse the repository at this point in the history
Signed-off-by: ryanwolhuter <[email protected]>
  • Loading branch information
ryanwolhuter committed Oct 13, 2023
1 parent fdc31c0 commit 27ae6cc
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 90 deletions.
84 changes: 45 additions & 39 deletions src/plugins/oSnap/components/HandleOutcomeUma.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import { formatUnits } from '@ethersproject/units';
import { getInstance } from '@snapshot-labs/lock/plugins/vue3';
import networks from '@snapshot-labs/snapshot.js/src/networks.json';
import { sleep } from '@snapshot-labs/snapshot.js/src/utils';
import type { Network, Transaction } from '../types';
import {
ProposalExecutionDetails,
type Network,
type Transaction
} from '../types';
import {
approveBond,
executeProposal,
getExecutionDetails,
getProposalExecutionDetails,
submitProposal
} from '../utils';
Expand Down Expand Up @@ -82,7 +86,6 @@ async function ensureRightNetwork(chainId: Network) {
const { formatDuration } = useIntl();
const { t } = useI18n();
const { clearBatchError } = useSafe();
const { web3 } = useWeb3();
const {
createPendingTransaction,
Expand All @@ -108,20 +111,20 @@ type QuestionState =
type Action1State = 'idle' | 'approve-bond' | 'submit-proposal';
type Action2State = 'idle' | 'execute-proposal';
const loading = ref(true);
const isLoading = ref(true);
const action1State = ref<Action1State>('idle');
const action2State = ref<Action2State>('idle');
const voteResultsConfirmed = ref(false);
const questionDetails = ref<Awaited<ReturnType<typeof getExecutionDetails>>>();
const closeModal = ref(false);
const proposalExecutionDetails = ref<ProposalExecutionDetails>();
const isModalOpen = ref(false);
function closeEvent() {
closeModal.value = false;
function closeModal() {
isModalOpen.value = false;
voteResultsConfirmed.value = false;
}
function showProposeModal() {
closeModal.value = true;
function openModal() {
isModalOpen.value = true;
voteResultsConfirmed.value = true;
}
Expand All @@ -132,9 +135,9 @@ function getFormattedTransactions() {
}
async function updateDetails() {
loading.value = true;
isLoading.value = true;
try {
questionDetails.value = await getExecutionDetails(
proposalExecutionDetails.value = await getProposalExecutionDetails(
props.network,
props.moduleAddress,
props.proposal.id,
Expand All @@ -144,7 +147,7 @@ async function updateDetails() {
} catch (e) {
console.error('Error loading uma execution details', e);
} finally {
loading.value = false;
isLoading.value = false;
}
}
Expand Down Expand Up @@ -224,7 +227,6 @@ async function onExecuteProposal() {
}
try {
clearBatchError();
const executingProposal = executeProposal(
getInstance().web3,
props.moduleAddress,
Expand Down Expand Up @@ -279,12 +281,12 @@ function wasProposalFinalized(proposal: Proposal) {
const questionState = computed<QuestionState>(() => {
if (!web3.value.account) return 'no-wallet-connection';
if (loading.value) return 'loading';
if (isLoading.value) return 'loading';
if (!questionDetails.value) return 'error';
if (!proposalExecutionDetails.value) return 'error';
const { assertionEvent, proposalExecuted, activeProposal, noTransactions } =
questionDetails.value;
proposalExecutionDetails.value;
if (noTransactions) return 'no-transactions';
Expand Down Expand Up @@ -344,7 +346,10 @@ onMounted(async () => {
{{ $t('safeSnap.labels.connectWallet') }}
</div>

<div v-if="questionState === 'loading'" class="my-4 grid place-items-center">
<div
v-if="questionState === 'loading'"
class="my-4 grid place-items-center"
>
<LoadingSpinner />
</div>
<div v-if="questionState === 'waiting-for-vote-finalize'" class="my-4">
Expand All @@ -357,7 +362,7 @@ onMounted(async () => {
class="my-4"
>
<div class="flex items-center">
<BaseButton @click="showProposeModal" class="mr-2 w-full">
<BaseButton @click="openModal" class="mr-2 w-full">
{{ $t('safeSnap.labels.confirmVoteResults') }}
</BaseButton>
</div>
Expand All @@ -370,11 +375,11 @@ onMounted(async () => {
<div
v-if="
questionState === 'waiting-for-proposal' &&
questionDetails?.needsBondApproval === true
proposalExecutionDetails?.needsBondApproval === true
"
class="my-4"
>
<div class="flex items-center my-4">
<div class="my-4 flex items-center">
<BaseButton
:loading="action1State === 'approve-bond'"
@click="onApproveBond"
Expand All @@ -399,12 +404,12 @@ onMounted(async () => {
<div
v-if="
questionState === 'waiting-for-proposal' &&
questionDetails?.needsBondApproval === false
proposalExecutionDetails?.needsBondApproval === false
"
class="my-4"
>
<div class="flex items-center">
<BaseModal :open="closeModal" @close="closeEvent">
<BaseModal :open="isModalOpen" @close="closeModal">
<template #header>
<h3 class="title">{{ $t('safeSnap.labels.request') }}</h3>
</template>
Expand All @@ -420,11 +425,11 @@ onMounted(async () => {
<span class="float-right text-skin-link">
{{
formatUnits(
questionDetails.minimumBond ?? 0,
questionDetails.decimals
proposalExecutionDetails.minimumBond ?? 0,
proposalExecutionDetails.decimals
) +
' ' +
questionDetails.symbol
proposalExecutionDetails.symbol
}}
</span>
</div>
Expand All @@ -433,7 +438,11 @@ onMounted(async () => {
$t('safeSnap.labels.challengePeriod')
}}</strong>
<span class="float-right text-skin-link">
{{ formatDuration(Number(questionDetails.livenessPeriod)) }}
{{
formatDuration(
Number(proposalExecutionDetails.livenessPeriod)
)
}}
</span>
</div>
</div>
Expand All @@ -446,8 +455,8 @@ onMounted(async () => {
</BaseMessage>
<BaseMessage
v-if="
Number(questionDetails.minimumBond.toString()) >
Number(questionDetails.userBalance.toString())
Number(proposalExecutionDetails.minimumBond.toString()) >
Number(proposalExecutionDetails.userBalance.toString())
"
level="warning-red"
>
Expand All @@ -460,8 +469,8 @@ onMounted(async () => {
@click="onSubmitProposal"
class="my-1 w-full"
:disabled="
Number(questionDetails.minimumBond.toString()) >
Number(questionDetails.userBalance.toString()) ||
Number(proposalExecutionDetails.minimumBond.toString()) >
Number(proposalExecutionDetails.userBalance.toString()) ||
Number(props.proposal.scores_total) < Number(quorum)
"
>
Expand All @@ -475,7 +484,7 @@ onMounted(async () => {
<div
v-if="
questionState === 'waiting-for-liveness' &&
questionDetails?.assertionEvent !== undefined
proposalExecutionDetails?.assertionEvent !== undefined
"
class="flex items-center justify-center self-stretch p-3 text-skin-link"
>
Expand All @@ -484,7 +493,7 @@ onMounted(async () => {
<strong>{{
'Proposal can be executed at ' +
new Date(
questionDetails.assertionEvent.expirationTimestamp.toNumber() *
proposalExecutionDetails.assertionEvent.expirationTimestamp.toNumber() *
1000
).toLocaleString()
}}</strong>
Expand All @@ -495,8 +504,8 @@ onMounted(async () => {
:href="
getOracleUiLink(
props.network,
questionDetails.assertionEvent.proposalTxHash,
questionDetails.assertionEvent.logIndex
proposalExecutionDetails.assertionEvent.proposalTxHash,
proposalExecutionDetails.assertionEvent.logIndex
)
"
class="rounded-lg border p-2 text-skin-text"
Expand All @@ -511,10 +520,7 @@ onMounted(async () => {
</BaseContainer>
</div>

<div
v-if="questionState === 'proposal-approved'"
class="my-4"
>
<div v-if="questionState === 'proposal-approved'" class="my-4">
<div class="flex items-center">
<BaseButton
:loading="action2State === 'execute-proposal'"
Expand Down
31 changes: 0 additions & 31 deletions src/plugins/oSnap/components/Tooltip.vue

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ const safeLink = computed(() =>
<i-ho-external-link class="ml-1" />
</a>
</p>
<p class="my-2">
<strong>Module address</strong
><span class="ml-2 inline-block break-all">{{ moduleAddress }}</span>
</p>
<p class="my-2">
<strong>Number of transactions</strong
><span class="ml-2 inline-block">{{ transactions.length }}</span>
Expand Down
45 changes: 45 additions & 0 deletions src/plugins/oSnap/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BigNumber } from '@ethersproject/bignumber';
import networks from '@snapshot-labs/snapshot.js/src/networks.json';
import { safePrefixes, transactionTypes } from './constants';

Expand Down Expand Up @@ -239,4 +240,48 @@ export type OsnapPluginData = {
*/
export type OsnapModelValue = {
oSnap: OsnapPluginData;
}

export type AssertionEvent = {
assertionId: string;
proposalHash: string;
proposalTxHash: string;
logIndex: number;
expirationTimestamp: BigNumber;
isExpired: boolean;
isSettled: boolean;
}

/**
* Represents the data associated with a proposal.
*
* Holds one object with this shape per proposal created. This is the shape of the data that is persisted by the plugin, along with information from the chain / graph about the Optimistic Oracle assertion associated with the proposal.
*
* We also include user data such as collateral balance and allowance so that we can determine if they can afford the bond associated with submitting a proposal.
*/
export type ProposalDetails = {
gnosisSafeAddress: string;
livenessPeriod: BigNumber | string;
oracleAddress: string;
rules: string;
collateral: string;
symbol: string;
minimumBond: BigNumber;
expiration: BigNumber;
allowance: BigNumber;
decimals: BigNumber;
userBalance: BigNumber;
needsBondApproval: boolean;
noTransactions: boolean;
activeProposal: boolean;
proposalExecuted: boolean;
assertionEvent: AssertionEvent | undefined;
}

/**
* Combines the proposal details with the proposal id and explanation.
*/
export type ProposalExecutionDetails = ProposalDetails & {
proposalId: string;
explanation: string;
}
Loading

0 comments on commit 27ae6cc

Please sign in to comment.