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: add support for starknet account to offchain actions #383

Merged
merged 36 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
931764e
feat: add setAlias to starknet eth sign
wa0x6e Jun 2, 2024
01525c0
Merge branch 'master' into feat-support-starknet-alias
wa0x6e Jun 5, 2024
ea49ce7
fix: use starknet-sig instead of ethereum-sig
wa0x6e Jun 5, 2024
ebb759c
fix: fix signature schema
wa0x6e Jun 5, 2024
9859d9c
fix: update type to include optional properties
wa0x6e Jun 5, 2024
b76f328
Merge branch 'master' into feat-support-starknet-alias
wa0x6e Jul 2, 2024
00fb949
fix: more robust starknet wallet detection
wa0x6e Jul 2, 2024
2bde73b
fix: enable back follow button for starknet wallet
wa0x6e Jul 2, 2024
b92f061
fix: fix typing
wa0x6e Jul 2, 2024
8b6c92d
feat: add support for starknet signature for offchain `send`
wa0x6e Jul 2, 2024
772bf73
fix: use string type to allow starknet address
wa0x6e Jul 4, 2024
df9d133
fix: enable space following/unfollowing for starknet wallets
wa0x6e Jul 4, 2024
abbb177
fix: enable user profile edition for starknet users
wa0x6e Jul 4, 2024
9938d89
fix: use formatted address in alias from
wa0x6e Jul 14, 2024
2300195
fix: always use padded starknet address
wa0x6e Jul 14, 2024
380dd76
Merge branch 'master' into feat-support-starknet-offchain
wa0x6e Jul 15, 2024
554c941
Merge branch 'master' into feat-support-starknet-offchain
wa0x6e Jul 17, 2024
8c9affd
fix: sign sn createAlias on the correct chainId
wa0x6e Jul 19, 2024
787b375
chore: fix tests
wa0x6e Jul 19, 2024
090a266
fix: avoid loading votes from incompatible networks
wa0x6e Jul 19, 2024
fc944ca
fix: add types and domain to starknet envelope
wa0x6e Jul 19, 2024
4aa3468
Update apps/ui/src/composables/useActions.ts
wa0x6e Jul 22, 2024
afb0d93
Merge branch 'master' into feat-support-starknet-offchain
wa0x6e Jul 23, 2024
4f3fa50
fix: revert unrelated change
wa0x6e Jul 24, 2024
e3b6e50
chore: removed unused import
wa0x6e Jul 24, 2024
222ca08
chore: add comments about confusing extra starknet params on evm enve…
wa0x6e Jul 24, 2024
2db20c3
chore: fix import order
wa0x6e Jul 24, 2024
2c5c658
fix: sign alias with first available starknet network
wa0x6e Jul 24, 2024
5468efd
Merge branch 'master' into feat-support-starknet-offchain
wa0x6e Jul 24, 2024
a8a49ec
chore: lint fix
wa0x6e Jul 24, 2024
f9f3e91
chore: add changesets
wa0x6e Jul 24, 2024
f5368c6
Merge branch 'master' into feat-support-starknet-offchain
wa0x6e Jul 24, 2024
f928679
revert: revert back ot use correct starknet chaind ID
wa0x6e Jul 27, 2024
313f2cd
fix: finish revert
wa0x6e Jul 27, 2024
01faa14
fix: fix leftover from merge
wa0x6e Jul 27, 2024
f47e9dc
refactor: simplify starknetNetworkId lookup
Sekhmet Jul 29, 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/calm-deers-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@snapshot-labs/sx": patch
---

add domain and types to starknet/starknet-sig envelope
5 changes: 5 additions & 0 deletions .changeset/funny-candles-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@snapshot-labs/sx": patch
---

always return padded addresses in starknet/starknet-sig envelope
5 changes: 5 additions & 0 deletions .changeset/red-mayflies-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@snapshot-labs/sx": patch
---

add support for sending starknet signed message to offchain/ethereum-sig
5 changes: 5 additions & 0 deletions .changeset/wild-news-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@snapshot-labs/sx": patch
---

add setAlias to starknet/starknet-sig
3 changes: 0 additions & 3 deletions apps/ui/src/components/ButtonFollow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ const { isSafeWallet } = useSafeWallet(
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(
() =>
Expand All @@ -28,7 +26,6 @@ const loading = computed(

<template>
<UiButton
v-if="!hidden"
:disabled="loading || isSafeWallet"
class="group"
:class="{ 'hover:border-skin-danger': spaceFollowed }"
Expand Down
22 changes: 20 additions & 2 deletions apps/ui/src/composables/useActions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { getInstance } from '@snapshot-labs/lock/plugins/vue3';
import { registerTransaction } from '@/helpers/mana';
import { convertToMetaTransactions } from '@/helpers/transactions';
import { getNetwork, getReadWriteNetwork, metadataNetwork } from '@/networks';
import {
enabledNetworks,

Check failure on line 5 in apps/ui/src/composables/useActions.ts

View workflow job for this annotation

GitHub Actions / lint-build-test

'enabledNetworks' is defined but never used
getNetwork,
getReadWriteNetwork,
metadataNetwork,
starknetNetworks

Check failure on line 9 in apps/ui/src/composables/useActions.ts

View workflow job for this annotation

GitHub Actions / lint-build-test

'starknetNetworks' is defined but never used
} from '@/networks';
import { STARKNET_CONNECTORS } from '@/networks/common/constants';
import { Connector, StrategyConfig } from '@/networks/types';
import {
Choice,
Expand All @@ -16,6 +23,13 @@
VoteType
} from '@/types';

const offchainToStarknetIds: Record<string, NetworkID> = {
s: 'sn',
's-tn': 'sn-sep'
};

const starknetNetworkId = offchainToStarknetIds[metadataNetwork];

export function useActions() {
const { mixpanel } = useMixpanel();
const uiStore = useUiStore();
Expand Down Expand Up @@ -126,7 +140,11 @@
}

async function getAliasSigner() {
const network = getNetwork(metadataNetwork);
const network = getNetwork(
STARKNET_CONNECTORS.includes(web3.value.type as Connector)
? starknetNetworkId
: metadataNetwork
);

return alias.getAliasWallet(address =>
wrapPromise(metadataNetwork, network.actions.setAlias(auth.web3, address))
Expand Down
1 change: 1 addition & 0 deletions apps/ui/src/networks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const evmNetworks: NetworkID[] = [
'linea-testnet'
];
export const offchainNetworks: NetworkID[] = ['s', 's-tn'];
export const starknetNetworks: NetworkID[] = ['sn', 'sn-sep'];
// This network is used for aliases/follows/profiles/explore page.
export const metadataNetwork: NetworkID =
import.meta.env.VITE_METADATA_NETWORK || 's';
Expand Down
7 changes: 6 additions & 1 deletion apps/ui/src/networks/starknet/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,12 @@ export function createActions(
},
followSpace: () => {},
unfollowSpace: () => {},
setAlias: () => {},
setAlias(web3: any, alias: string) {
return starkSigClient.setAlias({
signer: web3.provider.account,
data: { alias }
});
},
updateUser: () => {},
updateStatement: () => {},
send: (envelope: any) => starkSigClient.send(envelope) // TODO: extract it out of client to common helper
Expand Down
5 changes: 2 additions & 3 deletions apps/ui/src/stores/followedSpaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,15 @@ export const useFollowedSpacesStore = defineStore('followedSpaces', () => {
watch(
[
() => web3.value.account,
() => web3.value.type,
() => web3.value.authLoading,
() => authInitiated.value
],
async ([web3, walletType, authLoading, authInitiated]) => {
async ([web3, authLoading, authInitiated]) => {
if (!authInitiated || authLoading) return;

followedSpacesLoaded.value = false;

if (!web3 || walletType === 'argentx') {
if (!web3) {
followedSpacesIds.value = [];
followedSpacesLoaded.value = true;
return;
Expand Down
5 changes: 1 addition & 4 deletions apps/ui/src/views/User.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,7 @@ watchEffect(() => setTitle(`${user.value?.name || id.value} user profile`));
/>
<div class="absolute right-4 top-4 space-x-2 flex">
<DropdownShare :message="shareMsg" class="!px-0 w-[46px]" />
<UiTooltip
v-if="web3.account === user.id && web3.type !== 'argentx'"
title="Edit profile"
>
<UiTooltip v-if="web3.account === user.id" title="Edit profile">
<UiButton class="!px-0 w-[46px]" @click="modalOpenEditUser = true">
<IH-cog class="inline-block" />
</UiButton>
Expand Down
9 changes: 6 additions & 3 deletions packages/sx.js/src/clients/offchain/ethereum-sig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
weightedVoteTypes
} from './types';
import { offchainGoerli } from '../../../offchainNetworks';
import { OffchainNetworkConfig } from '../../../types';
import { OffchainNetworkConfig, SignatureData } from '../../../types';
import {
CancelProposal,
EIP712CancelProposalMessage,
Expand All @@ -38,7 +38,6 @@ import {
FollowSpace,
Propose,
SetAlias,
SignatureData,
UnfollowSpace,
UpdateProposal,
UpdateStatement,
Expand Down Expand Up @@ -120,9 +119,10 @@ export class EthereumSig {
signature: sig,
domain,
types,
primaryType,
message
} = envelope.signatureData!;
const payload = {
const payload: any = {
address,
sig,
data: {
Expand All @@ -132,6 +132,9 @@ export class EthereumSig {
}
};

// primaryType needs to be attached when sending starknet-sig generated payload
if (primaryType) payload.data.primaryType = primaryType;
wa0x6e marked this conversation as resolved.
Show resolved Hide resolved

const body = {
method: 'POST',
headers: {
Expand Down
6 changes: 3 additions & 3 deletions packages/sx.js/src/clients/offchain/ethereum-sig/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export const cancelProposalTypes = {

export const followSpaceTypes = {
Follow: [
{ name: 'from', type: 'address' },
{ name: 'from', type: 'string' },
{ name: 'network', type: 'string' },
{ name: 'space', type: 'string' },
{ name: 'timestamp', type: 'uint64' }
Expand All @@ -112,7 +112,7 @@ export const followSpaceTypes = {

export const unfollowSpaceTypes = {
Unfollow: [
{ name: 'from', type: 'address' },
{ name: 'from', type: 'string' },
{ name: 'network', type: 'string' },
{ name: 'space', type: 'string' },
{ name: 'timestamp', type: 'uint64' }
Expand All @@ -129,7 +129,7 @@ export const aliasTypes = {

export const updateUserTypes = {
Profile: [
{ name: 'from', type: 'address' },
{ name: 'from', type: 'string' },
{ name: 'timestamp', type: 'uint64' },
{ name: 'profile', type: 'string' }
]
Expand Down
14 changes: 1 addition & 13 deletions packages/sx.js/src/clients/offchain/types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
import {
TypedDataDomain,
TypedDataField
} from '@ethersproject/abstract-signer';
import { Privacy } from '../../types';
import { Privacy, SignatureData } from '../../types';

export type Choice = number | number[] | string | Record<string, number>;

export type SignatureData = {
address: string;
signature: string;
domain: TypedDataDomain;
types: Record<string, TypedDataField[]>;
message: Record<string, any>;
};

export type Envelope<
T extends
| Vote
Expand Down
45 changes: 42 additions & 3 deletions packages/sx.js/src/clients/starknet/starknet-sig/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import randomBytes from 'randombytes';
import { Account, CallData, shortString, typedData, uint256 } from 'starknet';
import {
Account,
CallData,
shortString,
typedData,
uint256,
validateAndParseAddress
} from 'starknet';
import {
aliasTypes,
baseDomain,
proposeTypes,
updateProposalTypes,
voteTypes
} from './types';
import {
Alias,
ClientConfig,
ClientOpts,
Envelope,
Propose,
SignatureData,
StarknetEIP712AliasMessage,
StarknetEIP712ProposeMessage,
StarknetEIP712UpdateProposalMessage,
StarknetEIP712VoteMessage,
Expand Down Expand Up @@ -60,6 +70,7 @@ export class StarknetSig {
| StarknetEIP712ProposeMessage
| StarknetEIP712UpdateProposalMessage
| StarknetEIP712VoteMessage
| StarknetEIP712AliasMessage
>(
signer: Account,
verifyingContract: string,
Expand All @@ -79,15 +90,16 @@ export class StarknetSig {
domain,
message
};

const signature = await signer.signMessage(data);

return {
address: signer.address,
address: validateAndParseAddress(signer.address),
signature: Array.isArray(signature)
? signature.map(v => `0x${BigInt(v).toString(16)}`)
: [`0x${signature.r.toString(16)}`, `0x${signature.s.toString(16)}`],
message,
domain,
types,
primaryType
};
}
Expand Down Expand Up @@ -217,4 +229,31 @@ export class StarknetSig {
data
};
}

public async setAlias({
signer,
data
}: {
signer: Account;
data: Alias;
}): Promise<Envelope<Alias>> {
const message = {
wa0x6e marked this conversation as resolved.
Show resolved Hide resolved
from: validateAndParseAddress(signer.address),
timestamp: parseInt((Date.now() / 1e3).toFixed()),
...data
};

const signatureData = await this.sign(
signer,
'',
message,
aliasTypes,
'SetAlias'
);

return {
signatureData,
data
};
}
}
9 changes: 9 additions & 0 deletions packages/sx.js/src/clients/starknet/starknet-sig/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,12 @@ export const updateProposalTypes = {
Strategy: sharedTypes.Strategy,
u256: sharedTypes.u256
};

export const aliasTypes = {
StarkNetDomain: domainTypes.StarkNetDomain,
SetAlias: [
{ name: 'from', type: 'ContractAddress' },
{ name: 'alias', type: 'string' },
{ name: 'timestamp', type: 'felt' }
]
};
22 changes: 19 additions & 3 deletions packages/sx.js/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { BigNumberish, Call, RpcProvider } from 'starknet';
import {
TypedDataDomain,
TypedDataField
} from '@ethersproject/abstract-signer';
import { BigNumberish, Call, RpcProvider, StarkNetType } from 'starknet';
import { NetworkConfig } from './networkConfig';
import { MetaTransaction } from '../utils/encoding';

Expand Down Expand Up @@ -133,14 +137,20 @@ 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;
commitTxId?: string;
commitHash?: string;
signature?: string[] | null;
signature?: string | string[] | null;
message?: Record<string, any>;
domain?: TypedDataDomain;
types?: Record<string, TypedDataField[] | StarkNetType[]>;
primaryType?: any;
};

Expand Down Expand Up @@ -182,6 +192,12 @@ export type StarknetEIP712VoteMessage = {
metadataUri: string[];
};

export type StarknetEIP712AliasMessage = {
alias: string;
from?: string;
timestamp?: number;
};

export type EIP712ProposeMessage = StarknetEIP712ProposeMessage & {
authenticator: string;
};
Expand Down
Loading
Loading