Skip to content

Commit

Permalink
feat: msig page refreshes on action
Browse files Browse the repository at this point in the history
  • Loading branch information
deansallinen committed Dec 4, 2024
1 parent 04617be commit c535c59
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import Account from '$lib/components/elements/account.svelte';
import { percentString } from '$lib/utils';
// import { Check, UserCheck } from 'lucide-svelte';
import { ApprovalManager } from './manager.svelte';
import ActionCard from '$lib/components/elements/action.svelte';
Expand Down Expand Up @@ -40,9 +39,8 @@
total_approvals.some((a) => wharf.session && a.equals(wharf.session.permissionLevel))
);
let userHasApproved = $derived(
accountHasApproved(wharf.session?.permissionLevel) || !!manager.txid
);
let transacting = $derived(manager.transacting);
let userHasApproved = $derived(manager.approved);
// Expiry date
let relativeTimeToExpiry = $derived(dayjs(proposal.transaction.expiration.toDate()).fromNow());
Expand All @@ -51,7 +49,7 @@
// Approval statistics
let totalRequested = $derived(total_approvals.length);
let totalApproved = $derived(provided_approvals.length);
let ratioApproved = $derived(totalApproved / totalRequested);
let ratioApproved = $derived((totalApproved / totalRequested) * 100);
// Actions
const handleApprove = () => manager.approve();
Expand All @@ -62,8 +60,11 @@
<MultiCard>
<div
id="msig-vis"
class="rounded-xl pb-4 pt-10"
style={`column-span:all;--bg-pos: calc(100% - ${percentString(ratioApproved)})`}
class="rounded-xl pb-4 pt-10 [column-span:all]"
style="
--bg-pos: calc(100% - {ratioApproved}%);
--ease: {userHasApproved ? 'ease-out' : 'ease-in'};
--duration: {userHasApproved ? '1000ms' : '200ms'}"
>
<div class="flex justify-between px-4 font-semibold">
<div class="">
Expand Down Expand Up @@ -139,9 +140,10 @@

{#if userIsApprover}
{#if userHasApproved}
<Button variant="secondary" onclick={handleUnapprove}>Unapprove</Button>
<Button variant="secondary" onclick={handleUnapprove} disabled={transacting}>Unapprove</Button
>
{:else}
<Button variant="primary" onclick={handleApprove}>Approve</Button>
<Button variant="primary" onclick={handleApprove} disabled={transacting}>Approve</Button>
{/if}
{/if}

Expand All @@ -164,13 +166,15 @@
theme(colors.mineShaft.950) 50%
);
background-size: 200% 100%;
background-position: var(--bg-pos, 100%);
background-position: var(--bg-pos);
transition: all var(--ease) var(--duration);
}
#msig-vis > div {
background: linear-gradient(to right, theme(colors.green.900) 50%, theme(colors.zinc.400) 50%);
background-size: 200% 100%;
background-position: var(--bg-pos, 100%);
background-position: var(--bg-pos);
background-clip: text;
color: transparent;
transition: all var(--ease) var(--duration);
}
</style>
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { invalidateAll } from '$app/navigation';
import type { WharfState } from '$lib/state/client/wharf.svelte';
import type { NetworkState } from '$lib/state/network.svelte';
import { Name, type Checksum256 } from '@wharfkit/antelope';
import { Name, PermissionLevel, type Checksum256 } from '@wharfkit/antelope';
import type { AnyAction } from '@wharfkit/session';

type Proposal = {
proposer: string;
name: string;
hash: Checksum256;
approvals: {
provided_approvals: PermissionLevel[];
};
};

export class ApprovalManager {
network: NetworkState | undefined = $state();
wharf: WharfState | undefined = $state();
proposal: Proposal;
error?: string = $state();
txid?: string = $state();
transacting = $state(false);
approved = $state(false);

constructor(network: NetworkState, proposal: Proposal) {
this.network = network;
Expand All @@ -29,78 +35,81 @@ export class ApprovalManager {

if (changed) {
this.error = '';
this.txid = '';
}

if (wharf !== this.wharf) {
this.wharf = wharf;

if (wharf.session) {
const permissionLevel = wharf.session.permissionLevel;
this.approved = this.proposal.approvals.provided_approvals.some((a: PermissionLevel) =>
a.equals(permissionLevel)
);
}
}
}

async approve() {
async transact(action: AnyAction) {
try {
if (!this.network || !this.wharf || !this.wharf.session) {
throw new Error("Can't sign, data not ready");
this.transacting = true;

if (!this.wharf) {
throw new Error("Can't sign, wharf not ready");
}
const action = this.network.contracts.msig.action('approve', {
proposer: Name.from(this.proposal.proposer),
proposal_name: Name.from(this.proposal.name),
level: this.wharf.session.permissionLevel,
proposal_hash: this.proposal.hash
});

const result = await this.wharf.transact({ action });

this.txid = result.response?.transaction_id;
if (!this.txid) {
const txid = result.response?.transaction_id;
if (!txid) {
throw Error('No transaction id');
}
} catch (e) {
this.error = String(e);
} finally {
this.transacting = false;
invalidateAll(); // Re-runs the load function to refresh table data
}
}

async unapprove() {
try {
if (!this.network || !this.wharf || !this.wharf.session) {
throw new Error("Can't sign, data not ready");
}
const action = this.network.contracts.msig.action('unapprove', {
proposer: Name.from(this.proposal.proposer),
proposal_name: Name.from(this.proposal.name),
level: this.wharf.session.permissionLevel
});
async approve() {
if (!this.network || !this.wharf || !this.wharf.session) {
throw new Error("Can't sign, data not ready");
}
const action = this.network.contracts.msig.action('approve', {
proposer: Name.from(this.proposal.proposer),
proposal_name: Name.from(this.proposal.name),
level: this.wharf.session.permissionLevel,
proposal_hash: this.proposal.hash
});

const result = await this.wharf.transact({ action });
await this.transact(action);
this.approved = true;
}

this.txid = result.response?.transaction_id;
if (!this.txid) {
throw Error('No transaction id');
}
} catch (e) {
this.error = String(e);
async unapprove() {
if (!this.network || !this.wharf || !this.wharf.session) {
throw new Error("Can't sign, data not ready");
}
const action = this.network.contracts.msig.action('unapprove', {
proposer: Name.from(this.proposal.proposer),
proposal_name: Name.from(this.proposal.name),
level: this.wharf.session.permissionLevel
});

await this.transact(action);
this.approved = false;
}

async execute() {
try {
if (!this.network || !this.wharf || !this.wharf.session) {
throw new Error("Can't sign, data not ready");
}
const action = this.network.contracts.msig.action('exec', {
proposer: Name.from(this.proposal.proposer),
proposal_name: Name.from(this.proposal.name),
executer: this.wharf.session.actor
});

const result = await this.wharf.transact({ action });

this.txid = result.response?.transaction_id;
if (!this.txid) {
throw Error('No transaction id');
}
} catch (e) {
this.error = String(e);
if (!this.network || !this.wharf || !this.wharf.session) {
throw new Error("Can't sign, data not ready");
}
const action = this.network.contracts.msig.action('exec', {
proposer: Name.from(this.proposal.proposer),
proposal_name: Name.from(this.proposal.name),
executer: this.wharf.session.actor
});

this.transact(action);
}
}

0 comments on commit c535c59

Please sign in to comment.