Skip to content

Commit

Permalink
feat: added multisig profile contract (#428)
Browse files Browse the repository at this point in the history
* feat: added multisig profile contract

* feat: querying from contract if address is multisig

* ref: update address

* feat: added address to object
  • Loading branch information
MrX-SNX authored Aug 31, 2024
1 parent df8b368 commit c737b3a
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 49 deletions.
90 changes: 55 additions & 35 deletions governance/ui/src/mutations/useUpdateUserDetailsMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useGetIsUUIDValidQuery } from '../queries/';
import { utils } from 'ethers';
import { GetUserDetails } from '../queries/useGetUserDetailsQuery';
import { useWallet, useSigner } from '../queries/useWallet';
import { profileContract } from '../utils/contracts';

type UpdateUserDetailsResponse = {
data: GetUserDetails & {
Expand Down Expand Up @@ -107,47 +108,66 @@ function useUpdateUserDetailsMutation() {
return useMutation({
mutationKey: ['updateUserDetails'],
mutationFn: async (userProfile: GetUserDetails) => {
let signedInUuid = '';
if (!isUuidValidQuery.data) {
signedInUuid = (await boardroomSignIn()) || '';
}
if (activeWallet?.address) {
const body = {
...userProfile,
uuid: signedInUuid,
};
const updateUserDetailsResponse = await fetch(
UPDATE_USER_DETAILS_API_URL(activeWallet.address),
const address = await signer?.getAddress();
const isContract = await signer?.provider.getCode(address || '');
if (isContract !== '0x' && signer) {
await profileContract.connect(signer).updateProfile(
{
username: userProfile.username,
about: userProfile.about,
github: userProfile.github,
twitter: userProfile.twitter,
discord: userProfile.discord,
delegationPitch: userProfile.delegationPitch,
},
{
method: 'POST',
body: JSON.stringify(body),
maxPriorityFeePerGas: utils.parseUnits('1', 'gwei'),
maxFeePerGas: utils.parseUnits('2', 'gwei'),
}
);

const updateUserDetailsResult =
(await updateUserDetailsResponse.json()) as UpdateUserDetailsResponse;

let updateDelegationPitchResult = {
data: {},
};

if (userProfile.delegationPitch) {
const delegationPitchesBody = {
protocol: 'synthetix',
address: activeWallet.address,
delegationPitch: userProfile.delegationPitch,
} else {
let signedInUuid = '';
if (!isUuidValidQuery.data) {
signedInUuid = (await boardroomSignIn()) || '';
}
if (activeWallet?.address) {
const body = {
...userProfile,
uuid: signedInUuid,
};
const delegationUpdateReponse = await fetch(UPDATE_USER_PITCH_FOR_PROTOCOL, {
method: 'POST',
body: JSON.stringify(delegationPitchesBody),
});
updateDelegationPitchResult = await delegationUpdateReponse.json();
}
const updateUserDetailsResponse = await fetch(
UPDATE_USER_DETAILS_API_URL(activeWallet.address),
{
method: 'POST',
body: JSON.stringify(body),
}
);

const updateUserDetailsResult =
(await updateUserDetailsResponse.json()) as UpdateUserDetailsResponse;

let updateDelegationPitchResult = {
data: {},
};

return { ...updateUserDetailsResult.data, ...updateDelegationPitchResult.data };
} else {
return new Error();
if (userProfile.delegationPitch) {
const delegationPitchesBody = {
protocol: 'synthetix',
address: activeWallet.address,
delegationPitch: userProfile.delegationPitch,
uuid: signedInUuid,
};
const delegationUpdateReponse = await fetch(UPDATE_USER_PITCH_FOR_PROTOCOL, {
method: 'POST',
body: JSON.stringify(delegationPitchesBody),
});
updateDelegationPitchResult = await delegationUpdateReponse.json();
}

return { ...updateUserDetailsResult.data, ...updateDelegationPitchResult.data };
} else {
return new Error();
}
}
},

Expand Down
52 changes: 39 additions & 13 deletions governance/ui/src/queries/useGetUserDetailsQuery.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { GET_PITCHES_FOR_USER_API_URL, GET_USER_DETAILS_API_URL } from '../utils/boardroom';
import { useQuery } from '@tanstack/react-query';
import { motherShipProvider } from '../utils/providers';
import { profileContract } from '../utils/contracts';

export type GetUserDetails = {
address: string;
Expand Down Expand Up @@ -46,9 +48,20 @@ export async function getUserDetails<T extends string | string[]>(
): Promise<(T extends string ? GetUserDetails : GetUserDetails[]) | undefined> {
if (typeof walletAddress === 'string') {
const randomNumber = Math.random();
const isMultiSig = await motherShipProvider(2192).getCode(walletAddress);
if (isMultiSig !== '0x') {
const profile = await profileContract
.connect(motherShipProvider(2192))
.getProfile(walletAddress);

return { ...profile, address: walletAddress } as T extends string
? GetUserDetails
: GetUserDetails[];
}
const userDetailsResponse = await fetch(GET_USER_DETAILS_API_URL(walletAddress), {
method: 'POST',
});

const userProfile = await userDetailsResponse.json();
const userPitchesResponse = await fetch(
GET_PITCHES_FOR_USER_API_URL(walletAddress, randomNumber),
Expand Down Expand Up @@ -83,6 +96,18 @@ export async function getUserDetails<T extends string | string[]>(
})
)
);

const multiSigQueries = await Promise.all(
walletAddress.map(async (address) => await motherShipProvider(2192).getCode(address))
);

const multiSigs = multiSigQueries.filter((sig) => sig !== '0x');
const multiSigsProfiles = await Promise.all(
multiSigs.map(async (address) => ({
...(await profileContract.connect(motherShipProvider(2192)).getProfile(address)),
address,
}))
);
const userProfile = await Promise.all(
userDetailsResponse.map(async (responses) => await responses.json())
);
Expand All @@ -103,18 +128,19 @@ export async function getUserDetails<T extends string | string[]>(
return data.delegationPitches?.filter((e: UserPitch) => e.protocol === 'synthetix');
});
}

return userProfile.map(({ data }) => {
try {
delete data.delegationPitches;
return {
...data,
delegationPitch: foundPitch,
};
} catch (error) {
console.error(error);
return userProfile;
}
}) as T extends string ? GetUserDetails : GetUserDetails[];
return userProfile
.map(({ data }) => {
try {
delete data.delegationPitches;
return {
...data,
delegationPitch: foundPitch,
};
} catch (error) {
console.error(error);
return userProfile;
}
})
.concat(multiSigsProfiles) as T extends string ? GetUserDetails : GetUserDetails[];
}
}
38 changes: 38 additions & 0 deletions governance/ui/src/utils/abi.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
export const profileAbi = [
{
inputs: [{ internalType: 'address', name: 'user', type: 'address' }],
name: 'getProfile',
outputs: [
{ internalType: 'string', name: 'username', type: 'string' },
{ internalType: 'string', name: 'about', type: 'string' },
{ internalType: 'string', name: 'twitter', type: 'string' },
{ internalType: 'string', name: 'github', type: 'string' },
{ internalType: 'string', name: 'discord', type: 'string' },
{ internalType: 'string', name: 'delegationPitch', type: 'string' },
],
stateMutability: 'view',
type: 'function',
},
{
inputs: [
{
components: [
{ internalType: 'string', name: 'username', type: 'string' },
{ internalType: 'string', name: 'about', type: 'string' },
{ internalType: 'string', name: 'twitter', type: 'string' },
{ internalType: 'string', name: 'github', type: 'string' },
{ internalType: 'string', name: 'discord', type: 'string' },
{ internalType: 'string', name: 'delegationPitch', type: 'string' },
],
internalType: 'struct UserProfile.ProfileUpdate',
name: 'update',
type: 'tuple',
},
],
name: 'updateProfile',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
];

export const multicallABI = [
{
inputs: [],
Expand Down
7 changes: 6 additions & 1 deletion governance/ui/src/utils/contracts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Contract } from 'ethers';
import { electionModuleABITest } from './abi';
import { electionModuleABITest, profileAbi } from './abi';
import { CouncilSlugs } from './councils';

export const isMotherchain = (chainId?: string | number) => {
Expand Down Expand Up @@ -57,3 +57,8 @@ const abiForSnapshotMock = [
'function balanceOfOnPeriod(address, uint256) view returns (uint256)',
'function setBalanceOfOnPeriod(address, uint256, uint256) external',
];

export const profileContract = new Contract(
'0x4F94C98825517688C088d565D3364B01748149a0',
profileAbi
);

0 comments on commit c737b3a

Please sign in to comment.