Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: vote and create/update proposals with session key #320

Closed
wants to merge 97 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
681b926
feat: add placeholder page for followings
wa0x6e Apr 9, 2024
17b5bbb
feat: redirect logged user to timeline when on homepage
wa0x6e Apr 9, 2024
3bb02c9
feat: add proposals timeline for followed spaces
wa0x6e Apr 9, 2024
6f53fd2
fix: fix proposal links when outside space route
wa0x6e Apr 9, 2024
69bf728
fix: fix invalid argument type
wa0x6e Apr 9, 2024
bec64be
chore: remove unused import
wa0x6e Apr 9, 2024
83695cd
fix: fix missing redirection on internal page nav
wa0x6e Apr 9, 2024
204f9cd
Merge branch 'master' into fix-217
wa0x6e Apr 9, 2024
6af5758
fix: handle network dynamically
wa0x6e Apr 9, 2024
1ec140f
Merge branch 'master' into fix-217
wa0x6e Apr 10, 2024
2bf20d4
feat: show space name in proposals list
wa0x6e Apr 11, 2024
8cfe54a
fix: avoid "no proposals" message flashing while logging in
wa0x6e Apr 11, 2024
3d59f7d
fix: remove auto redirection to timeline
wa0x6e Apr 11, 2024
a51de45
fix(ux): link space name to space
wa0x6e Apr 11, 2024
41ee28d
fix: resolve author domain name
wa0x6e Apr 11, 2024
7ec905c
fix: fix ignored space showing props
wa0x6e Apr 12, 2024
7319c14
fix(ui): fix proposal title not being truncated
wa0x6e Apr 12, 2024
6d4cc92
fix: rename routes
wa0x6e Apr 12, 2024
4f4400a
fix: add sidebar to timeline pages
wa0x6e Apr 12, 2024
66990d8
fix(ui): add back right sidebar
wa0x6e Apr 13, 2024
ee46b9b
chore: remove debug output
wa0x6e Apr 13, 2024
bda7d72
fix(ui): fix icon alignment
wa0x6e Apr 13, 2024
4a3b7d2
chore: put back line break
wa0x6e Apr 13, 2024
144c6ab
refactor: rename function to avoid confusion
wa0x6e Apr 13, 2024
1598a16
chore: return early on empty arg
wa0x6e Apr 13, 2024
fe493ef
fiix(ux): fix missing message when user has no followed spaces
wa0x6e Apr 13, 2024
d93417a
fix(ux): fix feed app nav on small screen
wa0x6e Apr 13, 2024
5566ed9
fix(ui): show right sidebar on explore page
wa0x6e Apr 13, 2024
e29eb85
refactor: DRY
wa0x6e Apr 13, 2024
81bef09
fix(ux): redirect guest user to landing when visiting /home
wa0x6e Apr 13, 2024
3de8ba8
fix: reset proposals on account change
wa0x6e Apr 13, 2024
752e70a
fix: highlighted voted proposals
wa0x6e Apr 13, 2024
6cd79e5
refactor: code improvement
wa0x6e Apr 13, 2024
afac8eb
refactor: use nested routes for home and explore page
wa0x6e Apr 13, 2024
ad3c8b9
chore: remove leftover
wa0x6e Apr 13, 2024
b5a7a88
fix: improve routes
wa0x6e Apr 13, 2024
c0298d5
chore: remove extra DIV
wa0x6e Apr 13, 2024
18c1b3b
fix: fix appNav visibility on small screen
wa0x6e Apr 13, 2024
8903447
fix(ui): show search form on home and explore page
wa0x6e Apr 13, 2024
08a59bf
refactor: improve code
wa0x6e Apr 13, 2024
1998f1d
refactor: delegate logged in user checking to parent route
wa0x6e Apr 13, 2024
2223b2b
refactor: fix order
wa0x6e Apr 17, 2024
92489e1
refactor: use computed value
wa0x6e Apr 17, 2024
361ef04
refactor: upgrade Follow to first class citizen
wa0x6e Apr 17, 2024
bdafff8
fix: add missing function to unsupported networks
wa0x6e Apr 17, 2024
bb16d7a
fix: skip timeline for unsupported wallet
wa0x6e Apr 18, 2024
09e78c2
refactor: move `loadFollows` to `useAccount` composable
wa0x6e Apr 18, 2024
2fcdd0f
refactor: improve typing
wa0x6e Apr 18, 2024
d1c6c2f
feat: replace space's star button by follow/unfollow status
wa0x6e Apr 18, 2024
83f9e71
refactor: move starredSpaces to useAccount
wa0x6e Apr 18, 2024
52fac22
refactor: rename variable for consistency
wa0x6e Apr 18, 2024
d9cdcee
fix: auto load followed spaces for connected account
wa0x6e Apr 18, 2024
2070c81
fix: keep sidebar order when mixing starred and followed spaces
wa0x6e Apr 18, 2024
baa4caa
fix: fix sidebar spaces not loading for guest user
wa0x6e Apr 19, 2024
6f8f6f2
feat: support custom order for multiple wallets
wa0x6e Apr 19, 2024
c5b2446
rerfactor: code improvement
wa0x6e Apr 19, 2024
44c4872
fix: fix followed space status not being loaded
wa0x6e Apr 19, 2024
966cde4
refactor: DRY
wa0x6e Apr 19, 2024
c62d5a7
refactor: avoid using computed value when not depending on ref
wa0x6e Apr 19, 2024
793d2e7
refactor: remove redundant condition
wa0x6e Apr 19, 2024
a66ec58
fix: fix wrong typing
wa0x6e Apr 19, 2024
7c875f8
refactor: avoid using computed value for simple values
wa0x6e Apr 19, 2024
23c8a10
feat: support offchain spaces follow and unfollow
wa0x6e Apr 20, 2024
bf4f3a9
fix: add follow/unfollow to all networks type
wa0x6e Apr 20, 2024
9e9561f
chore: update changeset
wa0x6e Apr 20, 2024
a3f3946
chore: add missing line break
wa0x6e Apr 20, 2024
6e3dc65
refactor: use simple spaceId instead of Space object
wa0x6e Apr 20, 2024
e0d1cc3
fix(ui): show loading icon while toggling space following
wa0x6e Apr 20, 2024
c81408d
fix(ux): disable button while working
wa0x6e Apr 20, 2024
619ae6b
feat: add support for offchain alias (session key)
wa0x6e Apr 21, 2024
1a34de7
fix: only prompt for alias tx signing
wa0x6e Apr 21, 2024
3028a34
fix(ui): allow sidebar scrolling
wa0x6e Apr 21, 2024
4204e5a
fix: handle client_error thrown by sequencer
wa0x6e Apr 21, 2024
c864696
chore: update changelog
wa0x6e Apr 22, 2024
39613a4
fix(ui): make sidebar scrollable
wa0x6e Apr 23, 2024
3483c55
fix(ui): remove tooltip on follow/unfollow button
wa0x6e Apr 23, 2024
853437c
fix(ui): add red border to unfollow button
wa0x6e Apr 23, 2024
f9071c8
fix: remove favorite feature on offchain spaces for starknet accounts
wa0x6e Apr 25, 2024
efd50bc
Merge branch 'master' into show-followed-spaces-in-sidebar
wa0x6e Apr 30, 2024
07e36d1
Merge branch 'master' into show-followed-spaces-in-sidebar
wa0x6e Apr 30, 2024
4f30785
fix: remove network from space Id
wa0x6e Apr 30, 2024
e646225
fix: move bookmarks to a Store
wa0x6e Apr 30, 2024
70ad395
refactor: code improvement
wa0x6e Apr 30, 2024
23c8246
refactor: code DRYing
wa0x6e Apr 30, 2024
6e0b892
fix: populate spaces store
wa0x6e Apr 30, 2024
f6ca94b
fix: fix spaces fetching for multiple network type
wa0x6e Apr 30, 2024
6c6c3c3
fix: fix variable name
wa0x6e Apr 30, 2024
108cbd8
chore: code cleaning
wa0x6e Apr 30, 2024
bdad473
fix(ux): add missing loading icon while loading follow list in sidebar
wa0x6e May 1, 2024
b384135
chore: remove debug output
wa0x6e May 1, 2024
593d68e
Merge branch 'master' into show-followed-spaces-in-sidebar
wa0x6e May 4, 2024
6727937
Merge branch 'master' into show-followed-spaces-in-sidebar
wa0x6e May 6, 2024
186d532
Merge branch 'show-followed-spaces-in-sidebar' into follow-and-unfoll…
wa0x6e May 6, 2024
474d1b7
fix: finish merge conflict
wa0x6e May 6, 2024
10b1dc9
Merge branch 'follow-and-unfollow-offchain-spaces' into add-session-keys
wa0x6e May 6, 2024
c1bc4d3
feat: enable vote and proposal creation/update with session key
wa0x6e May 6, 2024
5f65c1a
fix: fix missing actions
wa0x6e May 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nice-dogs-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@snapshot-labs/sx": patch
---

add space follow and unfollow support for OffchainEthereumSig
5 changes: 5 additions & 0 deletions .changeset/thick-carrots-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@snapshot-labs/sx": patch
---

add setAlias to OffchainEthereumSig
10 changes: 5 additions & 5 deletions apps/ui/src/components/App/Sidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
import draggable from 'vuedraggable';

const uiStore = useUiStore();
const spacesStore = useSpacesStore();
const bookmarksStore = useBookmarksStore();
</script>

<template>
<div class="w-[72px] border-r fixed left-0 top-0 bottom-0 text-center">
<div class="w-[72px] flex flex-col border-r fixed left-0 top-0 bottom-0 text-center h-screen">
<router-link :to="{ name: 'landing' }" class="h-[72px] block">
<IH-stop class="inline-block my-4 w-[32px] h-[32px] text-skin-link" />
</router-link>
<UiLoading v-if="!spacesStore.starredSpacesLoaded" />
<UiLoading v-if="!bookmarksStore.bookmarksLoaded" />
<draggable
v-else
v-model="spacesStore.starredSpaces"
v-model="bookmarksStore.bookmarkedSpaces"
:delay="100"
:delay-on-touch-only="true"
:touch-start-threshold="35"
:item-key="i => i"
v-bind="{ animation: 200 }"
class="space-y-3 p-2"
class="space-y-3 p-2 no-scrollbar overscroll-contain overflow-auto"
>
<template #item="{ element }">
<router-link
Expand Down
13 changes: 6 additions & 7 deletions apps/ui/src/components/SpacesListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { Space } from '@/types';

const props = defineProps<{ space: Space }>();

const spacesStore = useSpacesStore();
const bookmarksStore = useBookmarksStore();

const compositeSpaceId = `${props.space.network}:${props.space.id}`;
</script>

<template>
<router-link
:to="{ name: 'space-overview', params: { id: `${space.network}:${space.id}` } }"
:to="{ name: 'space-overview', params: { id: compositeSpaceId } }"
class="text-skin-text border rounded-lg block h-[280px] relative group overflow-hidden"
>
<SpaceCover :space="props.space" class="!rounded-none w-full h-[68px] absolute" />
Expand All @@ -24,12 +26,9 @@ const spacesStore = useSpacesStore();
</div>
<button
class="hidden group-hover:block absolute top-3 right-3 hover:text-skin-link"
@click.prevent="spacesStore.toggleSpaceStar(`${space.network}:${space.id}`)"
@click.prevent="bookmarksStore.toggleSpaceStar(compositeSpaceId)"
>
<IS-star
v-if="spacesStore.starredSpacesIds.includes(`${space.network}:${space.id}`)"
class="inline-block"
/>
<IS-star v-if="bookmarksStore.isStarred(compositeSpaceId)" class="inline-block" />
<IH-star v-else class="inline-block" />
</button>
<div class="px-4">
Expand Down
22 changes: 7 additions & 15 deletions apps/ui/src/composables/useAccount.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { getNetwork } from '@/networks';
import type { NetworkID, Proposal, Space, Vote } from '@/types';
import type { NetworkID, Proposal, Vote } from '@/types';

const votes: Ref<Record<Proposal['id'], Vote>> = ref({});
const follows: Ref<Space['id'][]> = ref([]);
const votes = ref<Record<Proposal['id'], Vote>>({});

export function useAccount() {
const { web3, web3Account } = useWeb3();
Expand All @@ -17,20 +16,13 @@ export function useAccount() {
votes.value = { ...votes.value, ...userVotes };
}

async function loadFollows(networkId: NetworkID) {
const { account, type } = web3.value;
if (!account || type === 'argentx') {
follows.value = [];
return;
}

const network = getNetwork(networkId);
follows.value = (await network.api.loadFollows(account)).map(follow => follow.space.id);
}

watchEffect(() => {
if (!web3Account.value) votes.value = {};
});

return { account: web3.value.account, loadVotes, loadFollows, votes, follows };
return {
account: web3.value.account,
votes,
loadVotes
};
}
71 changes: 66 additions & 5 deletions apps/ui/src/composables/useActions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getInstance } from '@snapshot-labs/lock/plugins/vue3';
import { getNetwork, getReadWriteNetwork } from '@/networks';
import { getNetwork, getReadWriteNetwork, offchainNetworks } from '@/networks';
import { registerTransaction } from '@/helpers/mana';
import { convertToMetaTransactions } from '@/helpers/transactions';
import type {
Expand All @@ -12,11 +12,14 @@ import type {
NetworkID,
VoteType
} from '@/types';
import type { Web3Provider } from '@ethersproject/providers';
import type { Connector, StrategyConfig } from '@/networks/types';
import type { Wallet } from '@ethersproject/wallet';

export function useActions() {
const { mixpanel } = useMixpanel();
const uiStore = useUiStore();
const alias = useAlias();
const { web3 } = useWeb3();
const { getCurrentFromDuration } = useMetaStore();
const { modalAccountOpen } = useModal();
Expand Down Expand Up @@ -103,6 +106,20 @@ export function useActions() {
modalAccountOpen.value = true;
}

async function aliasableSigner(networkId: NetworkID): Promise<Web3Provider | Wallet> {
if (!offchainNetworks.includes(networkId)) return auth.web3;

const network = getNetwork(networkId);

if (!(await alias.isValid())) {
await alias.create(address =>
wrapPromise(networkId, network.actions.setAlias(auth.web3, address))
);
}

return alias.wallet.value || auth.web3;
}

async function predictSpaceAddress(networkId: NetworkID, salt: string): Promise<string | null> {
if (!web3.value.account) {
forceLogin();
Expand Down Expand Up @@ -194,7 +211,7 @@ export function useActions() {
await wrapPromise(
proposal.network,
network.actions.vote(
auth.web3,
await aliasableSigner(proposal.network),
web3.value.type as Connector,
web3.value.account,
proposal,
Expand Down Expand Up @@ -248,7 +265,7 @@ export function useActions() {
await wrapPromise(
space.network,
network.actions.propose(
auth.web3,
await aliasableSigner(space.network),
web3.value.type as Connector,
web3.value.account,
space,
Expand Down Expand Up @@ -303,7 +320,7 @@ export function useActions() {
await wrapPromise(
space.network,
network.actions.updateProposal(
auth.web3,
await aliasableSigner(space.network),
web3.value.type as Connector,
web3.value.account,
space,
Expand Down Expand Up @@ -485,6 +502,48 @@ export function useActions() {
});
}

async function followSpace(networkId: NetworkID, spaceId: string) {
if (!web3.value.account) {
await forceLogin();
return false;
}

const network = getNetwork(networkId);

try {
await wrapPromise(
networkId,
network.actions.followSpace(await aliasableSigner(networkId), spaceId, web3.value.account)
);
} catch (e) {
uiStore.addNotification('error', e.message);
return false;
}

return true;
}

async function unfollowSpace(networkId: NetworkID, spaceId: string) {
if (!web3.value.account) {
await forceLogin();
return false;
}

const network = getNetwork(networkId);

try {
await wrapPromise(
networkId,
network.actions.unfollowSpace(await aliasableSigner(networkId), spaceId, web3.value.account)
);
} catch (e) {
uiStore.addNotification('error', e.message);
return false;
}

return true;
}

return {
predictSpaceAddress: wrapWithErrors(predictSpaceAddress),
deployDependency: wrapWithErrors(deployDependency),
Expand All @@ -503,6 +562,8 @@ export function useActions() {
setMaxVotingDuration: wrapWithErrors(setMaxVotingDuration),
transferOwnership: wrapWithErrors(transferOwnership),
updateStrategies: wrapWithErrors(updateStrategies),
delegate: wrapWithErrors(delegate)
delegate: wrapWithErrors(delegate),
followSpace: wrapWithErrors(followSpace),
unfollowSpace: wrapWithErrors(unfollowSpace)
};
}
50 changes: 50 additions & 0 deletions apps/ui/src/composables/useAlias.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Wallet } from '@ethersproject/wallet';
import { getDefaultProvider } from '@ethersproject/providers';
import pkg from '../../package.json';
import { enabledNetworks, getNetwork, offchainNetworks } from '@/networks';

const aliases = useStorage(`${pkg.name}.aliases`, {} as Record<string, string>);

const networkId = offchainNetworks.filter(network => enabledNetworks.includes(network))[0];
const network = getNetwork(networkId);

export function useAlias() {
const { web3 } = useWeb3();

const wallet = computed(() => {
const provider = getDefaultProvider();
const pk = aliases.value[web3.value.account];

if (!pk) return null;

return new Wallet(pk, provider);
});

async function create(actionFn: (address: string) => Promise<unknown>) {
const newAliasWallet = Wallet.createRandom();

await actionFn(newAliasWallet.address);

aliases.value = {
...aliases.value,
...{
[web3.value.account]: newAliasWallet.privateKey
}
};
}

async function isValid() {
if (!wallet.value) return false;

const registeredAlias = await network.api.loadAlias(web3.value.account, wallet.value.address);

if (!registeredAlias) return false;

return (
registeredAlias.address === web3.value.account &&
registeredAlias.alias === wallet.value.address
);
}

return { wallet, isValid, create };
}
3 changes: 3 additions & 0 deletions apps/ui/src/networks/common/graphqlApi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,9 @@ export function createApi(uri: string, networkId: NetworkID, opts: ApiOptions =
},
loadFollows: async () => {
return [] as Follow[];
},
loadAlias: async () => {
return null;
}
};
}
5 changes: 4 additions & 1 deletion apps/ui/src/networks/evm/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ export function createActions(
};
})
);
}
},
followSpace: () => {},
unfollowSpace: () => {},
setAlias() {}
};
}
Loading
Loading