From 931764ef9bef367d66f28bc8e4edf6d5079f842a Mon Sep 17 00:00:00 2001 From: Wan Qi Chen <495709+wa0x6e@users.noreply.github.com> Date: Sun, 2 Jun 2024 23:11:38 +0400 Subject: [PATCH 01/29] feat: add setAlias to starknet eth sign --- apps/ui/src/composables/useActions.ts | 8 +++++- apps/ui/src/networks/starknet/actions.ts | 7 +++++- .../clients/starknet/ethereum-sig/index.ts | 25 +++++++++++++++++-- .../clients/starknet/ethereum-sig/types.ts | 8 ++++++ packages/sx.js/src/types/index.ts | 10 +++++++- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/apps/ui/src/composables/useActions.ts b/apps/ui/src/composables/useActions.ts index 337d919d8..f5a4b9cfe 100644 --- a/apps/ui/src/composables/useActions.ts +++ b/apps/ui/src/composables/useActions.ts @@ -13,8 +13,12 @@ import type { VoteType } from '@/types'; import type { Connector, StrategyConfig } from '@/networks/types'; +import { starknetNetworks } from '@snapshot-labs/sx'; const offchainNetworkId = offchainNetworks.filter(network => enabledNetworks.includes(network))[0]; +const starknetNetworkId = (Object.keys(starknetNetworks) as NetworkID[]) + .filter(network => enabledNetworks.includes(network)) + .pop() as NetworkID; export function useActions() { const { mixpanel } = useMixpanel(); @@ -107,7 +111,9 @@ export function useActions() { } async function getAliasSigner() { - const network = getNetwork(offchainNetworkId); + const network = getNetwork( + web3.value.type === 'argentx' ? starknetNetworkId : offchainNetworkId + ); return alias.getAliasWallet(address => wrapPromise(offchainNetworkId, network.actions.setAlias(auth.web3, address)) diff --git a/apps/ui/src/networks/starknet/actions.ts b/apps/ui/src/networks/starknet/actions.ts index 93e6ed94b..b7de9566b 100644 --- a/apps/ui/src/networks/starknet/actions.ts +++ b/apps/ui/src/networks/starknet/actions.ts @@ -582,7 +582,12 @@ export function createActions( }, followSpace: () => {}, unfollowSpace: () => {}, - setAlias: () => {}, + setAlias(web3: any, alias: string) { + return ethSigClient.setAlias({ + signer: web3.getSigner(), + data: { alias } + }); + }, send: (envelope: any) => starkSigClient.send(envelope) // TODO: extract it out of client to common helper }; } diff --git a/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts b/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts index 22651378c..36b05a5ae 100644 --- a/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts +++ b/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts @@ -2,7 +2,7 @@ import randomBytes from 'randombytes'; import { Signer, TypedDataSigner, TypedDataField } from '@ethersproject/abstract-signer'; import { CallData, shortString } from 'starknet'; import { getStrategiesWithParams } from '../../../utils/strategies'; -import { proposeTypes, updateProposalTypes, voteTypes } from './types'; +import { proposeTypes, updateProposalTypes, voteTypes, aliasTypes } from './types'; import { ClientConfig, ClientOpts, @@ -10,9 +10,11 @@ import { Propose, UpdateProposal, Vote, + Alias, EIP712ProposeMessage, EIP712UpdateProposalMessage, EIP712VoteMessage, + EIP712AliasMessage, SignatureData } from '../../../types'; import { getRSVFromSig } from '../../../utils/encoding'; @@ -29,7 +31,11 @@ export class EthereumSig { } public async sign< - T extends EIP712ProposeMessage | EIP712UpdateProposalMessage | EIP712VoteMessage + T extends + | EIP712ProposeMessage + | EIP712UpdateProposalMessage + | EIP712VoteMessage + | EIP712AliasMessage >( signer: Signer & TypedDataSigner, message: T, @@ -164,4 +170,19 @@ export class EthereumSig { data }; } + + public async setAlias({ + signer, + data + }: { + signer: Signer & TypedDataSigner; + data: Alias; + }): Promise> { + const signatureData = await this.sign(signer, data, aliasTypes, 'SetAlias'); + + return { + signatureData, + data + }; + } } diff --git a/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts b/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts index de526e1ed..e3d4a5a70 100644 --- a/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts +++ b/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts @@ -50,3 +50,11 @@ export const updateProposalTypes = { ], Strategy: sharedTypes.Strategy }; + +export const aliasTypes = { + Alias: [ + { name: 'from', type: 'address' }, + { name: 'alias', type: 'address' }, + { name: 'timestamp', type: 'uint64' } + ] +}; diff --git a/packages/sx.js/src/types/index.ts b/packages/sx.js/src/types/index.ts index 4b732dae8..e4c60e7cc 100644 --- a/packages/sx.js/src/types/index.ts +++ b/packages/sx.js/src/types/index.ts @@ -131,7 +131,11 @@ export type Vote = { choice: Choice; }; -export type Message = Propose | Vote | UpdateProposal; +export type Alias = { + alias: string; +}; + +export type Message = Propose | Vote | UpdateProposal | Alias; export type SignatureData = { address: string; @@ -197,6 +201,10 @@ export type EIP712VoteMessage = Omit & proposalId: string; }; +export type EIP712AliasMessage = { + alias: string; +}; + export type StrategiesAddresses = { index: number; address: string }[]; export type ExecutionInput = { From ea49ce74f1839b507821e42371c32052fd3fbccd Mon Sep 17 00:00:00 2001 From: Wan Qi Chen <495709+wa0x6e@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:36:13 +0400 Subject: [PATCH 02/29] fix: use starknet-sig instead of ethereum-sig --- apps/ui/src/networks/starknet/actions.ts | 4 +-- .../clients/starknet/ethereum-sig/index.ts | 25 ++----------------- .../clients/starknet/ethereum-sig/types.ts | 8 ------ .../clients/starknet/starknet-sig/index.ts | 20 ++++++++++++++- .../clients/starknet/starknet-sig/types.ts | 8 ++++++ packages/sx.js/src/types/index.ts | 8 +++--- 6 files changed, 35 insertions(+), 38 deletions(-) diff --git a/apps/ui/src/networks/starknet/actions.ts b/apps/ui/src/networks/starknet/actions.ts index b7de9566b..36d7203c5 100644 --- a/apps/ui/src/networks/starknet/actions.ts +++ b/apps/ui/src/networks/starknet/actions.ts @@ -583,8 +583,8 @@ export function createActions( followSpace: () => {}, unfollowSpace: () => {}, setAlias(web3: any, alias: string) { - return ethSigClient.setAlias({ - signer: web3.getSigner(), + return starkSigClient.setAlias({ + signer: web3.provider.account, data: { alias } }); }, diff --git a/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts b/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts index 36b05a5ae..22651378c 100644 --- a/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts +++ b/packages/sx.js/src/clients/starknet/ethereum-sig/index.ts @@ -2,7 +2,7 @@ import randomBytes from 'randombytes'; import { Signer, TypedDataSigner, TypedDataField } from '@ethersproject/abstract-signer'; import { CallData, shortString } from 'starknet'; import { getStrategiesWithParams } from '../../../utils/strategies'; -import { proposeTypes, updateProposalTypes, voteTypes, aliasTypes } from './types'; +import { proposeTypes, updateProposalTypes, voteTypes } from './types'; import { ClientConfig, ClientOpts, @@ -10,11 +10,9 @@ import { Propose, UpdateProposal, Vote, - Alias, EIP712ProposeMessage, EIP712UpdateProposalMessage, EIP712VoteMessage, - EIP712AliasMessage, SignatureData } from '../../../types'; import { getRSVFromSig } from '../../../utils/encoding'; @@ -31,11 +29,7 @@ export class EthereumSig { } public async sign< - T extends - | EIP712ProposeMessage - | EIP712UpdateProposalMessage - | EIP712VoteMessage - | EIP712AliasMessage + T extends EIP712ProposeMessage | EIP712UpdateProposalMessage | EIP712VoteMessage >( signer: Signer & TypedDataSigner, message: T, @@ -170,19 +164,4 @@ export class EthereumSig { data }; } - - public async setAlias({ - signer, - data - }: { - signer: Signer & TypedDataSigner; - data: Alias; - }): Promise> { - const signatureData = await this.sign(signer, data, aliasTypes, 'SetAlias'); - - return { - signatureData, - data - }; - } } diff --git a/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts b/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts index e3d4a5a70..de526e1ed 100644 --- a/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts +++ b/packages/sx.js/src/clients/starknet/ethereum-sig/types.ts @@ -50,11 +50,3 @@ export const updateProposalTypes = { ], Strategy: sharedTypes.Strategy }; - -export const aliasTypes = { - Alias: [ - { name: 'from', type: 'address' }, - { name: 'alias', type: 'address' }, - { name: 'timestamp', type: 'uint64' } - ] -}; diff --git a/packages/sx.js/src/clients/starknet/starknet-sig/index.ts b/packages/sx.js/src/clients/starknet/starknet-sig/index.ts index 24d55cfba..7776b9693 100644 --- a/packages/sx.js/src/clients/starknet/starknet-sig/index.ts +++ b/packages/sx.js/src/clients/starknet/starknet-sig/index.ts @@ -1,7 +1,7 @@ import randomBytes from 'randombytes'; import { Account, CallData, shortString, typedData, uint256 } from 'starknet'; import { getStrategiesWithParams } from '../../../utils/strategies'; -import { baseDomain, proposeTypes, updateProposalTypes, voteTypes } from './types'; +import { aliasTypes, baseDomain, proposeTypes, updateProposalTypes, voteTypes } from './types'; import { ClientConfig, ClientOpts, @@ -9,9 +9,11 @@ import { Propose, UpdateProposal, Vote, + Alias, StarknetEIP712ProposeMessage, StarknetEIP712UpdateProposalMessage, StarknetEIP712VoteMessage, + StarknetEIP712AliasMessage, SignatureData } from '../../../types'; @@ -55,6 +57,7 @@ export class StarknetSig { | StarknetEIP712ProposeMessage | StarknetEIP712UpdateProposalMessage | StarknetEIP712VoteMessage + | StarknetEIP712AliasMessage >( signer: Account, verifyingContract: string, @@ -198,4 +201,19 @@ export class StarknetSig { data }; } + + public async setAlias({ + signer, + data + }: { + signer: Account; + data: Alias; + }): Promise> { + const signatureData = await this.sign(signer, '', data, aliasTypes, 'SetAlias'); + + return { + signatureData, + data + }; + } } diff --git a/packages/sx.js/src/clients/starknet/starknet-sig/types.ts b/packages/sx.js/src/clients/starknet/starknet-sig/types.ts index 1ae6bfa17..2378dd410 100644 --- a/packages/sx.js/src/clients/starknet/starknet-sig/types.ts +++ b/packages/sx.js/src/clients/starknet/starknet-sig/types.ts @@ -67,3 +67,11 @@ export const updateProposalTypes = { Strategy: sharedTypes.Strategy, u256: sharedTypes.u256 }; + +export const aliasTypes = { + Alias: [ + { name: 'from', type: 'address' }, + { name: 'alias', type: 'address' }, + { name: 'timestamp', type: 'uint64' } + ] +}; diff --git a/packages/sx.js/src/types/index.ts b/packages/sx.js/src/types/index.ts index e4c60e7cc..ebd1b9faf 100644 --- a/packages/sx.js/src/types/index.ts +++ b/packages/sx.js/src/types/index.ts @@ -184,6 +184,10 @@ export type StarknetEIP712VoteMessage = { metadataUri: string[]; }; +export type StarknetEIP712AliasMessage = { + alias: string; +}; + export type EIP712ProposeMessage = StarknetEIP712ProposeMessage & { authenticator: string; }; @@ -201,10 +205,6 @@ export type EIP712VoteMessage = Omit & proposalId: string; }; -export type EIP712AliasMessage = { - alias: string; -}; - export type StrategiesAddresses = { index: number; address: string }[]; export type ExecutionInput = { From ebb759cf4477c911d5e5f8b1601ea132862222c7 Mon Sep 17 00:00:00 2001 From: Wan Qi Chen <495709+wa0x6e@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:52:30 +0400 Subject: [PATCH 03/29] fix: fix signature schema --- .../sx.js/src/clients/starknet/starknet-sig/index.ts | 9 +++++++-- .../sx.js/src/clients/starknet/starknet-sig/types.ts | 9 +++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/sx.js/src/clients/starknet/starknet-sig/index.ts b/packages/sx.js/src/clients/starknet/starknet-sig/index.ts index 7776b9693..639ae3b3f 100644 --- a/packages/sx.js/src/clients/starknet/starknet-sig/index.ts +++ b/packages/sx.js/src/clients/starknet/starknet-sig/index.ts @@ -77,7 +77,6 @@ export class StarknetSig { domain, message }; - const signature = await signer.signMessage(data); return { @@ -209,7 +208,13 @@ export class StarknetSig { signer: Account; data: Alias; }): Promise> { - const signatureData = await this.sign(signer, '', data, aliasTypes, 'SetAlias'); + const message = { + from: signer.address, + timestamp: parseInt((Date.now() / 1e3).toFixed()), + ...data + }; + + const signatureData = await this.sign(signer, '', message, aliasTypes, 'SetAlias'); return { signatureData, diff --git a/packages/sx.js/src/clients/starknet/starknet-sig/types.ts b/packages/sx.js/src/clients/starknet/starknet-sig/types.ts index 2378dd410..3468a3cd2 100644 --- a/packages/sx.js/src/clients/starknet/starknet-sig/types.ts +++ b/packages/sx.js/src/clients/starknet/starknet-sig/types.ts @@ -69,9 +69,10 @@ export const updateProposalTypes = { }; export const aliasTypes = { - Alias: [ - { name: 'from', type: 'address' }, - { name: 'alias', type: 'address' }, - { name: 'timestamp', type: 'uint64' } + StarkNetDomain: domainTypes.StarkNetDomain, + SetAlias: [ + { name: 'from', type: 'ContractAddress' }, + { name: 'alias', type: 'string' }, + { name: 'timestamp', type: 'felt' } ] }; From 9859d9cfd05a634fda3076eba703c0d61abbbf76 Mon Sep 17 00:00:00 2001 From: Wan Qi Chen <495709+wa0x6e@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:56:39 +0400 Subject: [PATCH 04/29] fix: update type to include optional properties --- packages/sx.js/src/types/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/sx.js/src/types/index.ts b/packages/sx.js/src/types/index.ts index ebd1b9faf..804c478eb 100644 --- a/packages/sx.js/src/types/index.ts +++ b/packages/sx.js/src/types/index.ts @@ -186,6 +186,8 @@ export type StarknetEIP712VoteMessage = { export type StarknetEIP712AliasMessage = { alias: string; + from?: string; + timestamp?: number; }; export type EIP712ProposeMessage = StarknetEIP712ProposeMessage & { From 00fb94969792fa7fa30fa849847b3bcc03ca2283 Mon Sep 17 00:00:00 2001 From: Wan Qi Chen <495709+wa0x6e@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:13:57 +0900 Subject: [PATCH 05/29] fix: more robust starknet wallet detection --- apps/ui/src/composables/useActions.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/ui/src/composables/useActions.ts b/apps/ui/src/composables/useActions.ts index 16f33f663..75d370a57 100644 --- a/apps/ui/src/composables/useActions.ts +++ b/apps/ui/src/composables/useActions.ts @@ -15,6 +15,7 @@ import type { } from '@/types'; import type { Connector, StrategyConfig } from '@/networks/types'; import { starknetNetworks } from '@snapshot-labs/sx'; +import { STARKNET_CONNECTORS } from '@/networks/common/constants'; const offchainNetworkId = offchainNetworks.filter(network => enabledNetworks.includes(network))[0]; const starknetNetworkId = (Object.keys(starknetNetworks) as NetworkID[]) @@ -123,7 +124,9 @@ export function useActions() { async function getAliasSigner() { const network = getNetwork( - web3.value.type === 'argentx' ? starknetNetworkId : offchainNetworkId + STARKNET_CONNECTORS.includes(web3.value.type as Connector) + ? starknetNetworkId + : offchainNetworkId ); return alias.getAliasWallet(address => From 2bde73b56d59ae5d1495d5c2c0ad8c9817e0bea7 Mon Sep 17 00:00:00 2001 From: Wan Qi Chen <495709+wa0x6e@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:22:45 +0900 Subject: [PATCH 06/29] fix: enable back follow button for starknet wallet --- apps/ui/src/components/ButtonFollow.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/ui/src/components/ButtonFollow.vue b/apps/ui/src/components/ButtonFollow.vue index 1664139be..25d4affb6 100644 --- a/apps/ui/src/components/ButtonFollow.vue +++ b/apps/ui/src/components/ButtonFollow.vue @@ -9,10 +9,8 @@ const spaceIdComposite = `${props.space.network}:${props.space.id}`; const { isSafeWallet } = useSafeWallet(props.space.network, props.space.snapshot_chain_id); const followedSpacesStore = useFollowedSpacesStore(); -const { web3 } = useWeb3(); const spaceFollowed = computed(() => followedSpacesStore.isFollowed(spaceIdComposite)); -const hidden = computed(() => web3.value?.type === 'argentx'); const loading = computed( () => @@ -23,7 +21,6 @@ const loading = computed(