Skip to content

Commit

Permalink
refactor: allow any network to be used in delegations
Browse files Browse the repository at this point in the history
  • Loading branch information
Sekhmet committed Oct 25, 2024
1 parent db2dde3 commit accc9b4
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 55 deletions.
11 changes: 7 additions & 4 deletions apps/ui/src/components/Modal/Delegate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ const sending = ref(false);
const formErrors = ref({} as Record<string, any>);
async function handleSubmit() {
if (!props.delegation.apiType || !props.delegation.contractAddress) {
if (
!props.delegation.apiType ||
!props.delegation.contractAddress ||
!props.delegation.chainId
) {
return;
}
Expand All @@ -56,11 +60,10 @@ async function handleSubmit() {
try {
await delegate(
props.space,
props.delegation.contractNetwork,
props.delegation.apiType,
form.delegatee,
`${props.delegation.contractNetwork}:${props.delegation.contractAddress}`,
props.delegation.chainId ?? undefined
props.delegation.contractAddress,
props.delegation.chainId
);
emit('close');
} catch (e) {
Expand Down
12 changes: 4 additions & 8 deletions apps/ui/src/components/Modal/DelegationConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const DEFAULT_FORM_STATE = {
name: '',
apiType: null,
apiUrl: null,
contractNetwork: null,
contractAddress: null,
chainId: null
};
Expand All @@ -27,10 +26,6 @@ const showPicker = ref(false);
const searchValue = ref('');
const form: Ref<SpaceMetadataDelegation> = ref(clone(DEFAULT_FORM_STATE));
const networkField = computed(() =>
offchainNetworks.includes(props.networkId) ? 'chainId' : 'contractNetwork'
);
const definition = computed(() => {
return {
type: 'object',
Expand Down Expand Up @@ -69,14 +64,15 @@ const definition = computed(() => {
'https://api.thegraph.com/subgraphs/name/arr00/uniswap-governance-v2'
]
},
[networkField.value]: {
type: ['string', 'number', 'null'],
chainId: {
type: ['number', 'null'],
format: 'network',
networkId: props.networkId,
networksListKind: 'full',
title: 'Delegation contract network',
nullable: true
},
...(form.value[networkField.value] !== null
...(form.value.chainId !== null
? {
contractAddress: {
type: 'string',
Expand Down
3 changes: 3 additions & 0 deletions apps/ui/src/components/Modal/TreasuryConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ const definition = computed(() => {
type: ['string', 'number', 'null'],
format: 'network',
networkId: props.networkId,
networksListKind: offchainNetworks.includes(props.networkId)
? 'full'
: 'builtin',
title: 'Treasury network',
nullable: true
},
Expand Down
14 changes: 1 addition & 13 deletions apps/ui/src/components/SpaceDelegates.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,11 @@ const {
);
const { web3 } = useWeb3();
const currentNetwork = computed(() => {
if (!props.delegation.contractNetwork) return null;
try {
return getNetwork(props.delegation.contractNetwork);
} catch (e) {
return null;
}
});
const spaceKey = computed(() => `${props.space.network}:${props.space.id}`);
function getExplorerUrl(address: string, type: 'address' | 'token') {
let url: string | null = null;
if (currentNetwork.value) {
url = currentNetwork.value.helpers.getExplorerUrl(address, type);
} else if (props.delegation.chainId) {
if (props.delegation.chainId) {
url = getGenericExplorerUrl(props.delegation.chainId, address, type);
} else {
return null;
Expand Down
5 changes: 3 additions & 2 deletions apps/ui/src/components/Ui/SelectorNetwork.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import networks from '@snapshot-labs/snapshot.js/src/networks.json';
import { getUrl } from '@/helpers/utils';
import { enabledNetworks, getNetwork, offchainNetworks } from '@/networks';
import { enabledNetworks, getNetwork } from '@/networks';
import { METADATA as STARKNET_NETWORK_METADATA } from '@/networks/starknet';
import { BaseDefinition, NetworkID } from '@/types';
Expand All @@ -12,11 +12,12 @@ const network = defineModel<string | number | null>({
const props = defineProps<{
definition: BaseDefinition<string | number | null> & {
networkId: NetworkID;
networksListKind?: 'full' | 'builtin';
};
}>();
const options = computed(() => {
if (offchainNetworks.includes(props.definition.networkId)) {
if (props.definition.networksListKind === 'full') {
const baseNetworks = Object.entries(networks)
.filter(([, network]) => {
if (
Expand Down
19 changes: 8 additions & 11 deletions apps/ui/src/composables/useActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,22 +574,19 @@ export function useActions() {

async function delegate(
space: Space,
networkId: NetworkID | null,
delegationType: DelegationType,
delegatee: string,
delegationContract: string,
chainIdOverride?: ChainId
chainId: ChainId
) {
if (!web3.value.account) return await forceLogin();

const isEvmNetwork = typeof chainIdOverride === 'number';
const actionNetwork =
networkId ??
(isEvmNetwork
? 'eth'
: (Object.entries(METADATA).find(
([, metadata]) => metadata.chainId === chainIdOverride
)?.[0] as NetworkID));
const isEvmNetwork = typeof chainId === 'number';
const actionNetwork = isEvmNetwork
? 'eth'
: (Object.entries(METADATA).find(
([, metadata]) => metadata.chainId === chainId
)?.[0] as NetworkID);
if (!actionNetwork) throw new Error('Failed to detect action network');

const network = getReadWriteNetwork(actionNetwork);
Expand All @@ -603,7 +600,7 @@ export function useActions() {
delegationType,
delegatee,
delegationContract,
chainIdOverride
chainId
)
);
}
Expand Down
5 changes: 3 additions & 2 deletions apps/ui/src/helpers/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('utils', () => {
apiType: 'governor-subgraph',
apiUrl:
'https://thegraph.com/hosted-service/subgraph/arr00/uniswap-governance-v2',
contractNetwork: 'sep',
chainId: 11155111,
contractAddress: '0x000000000000000000000000000000000000dead'
}
]
Expand Down Expand Up @@ -124,7 +124,8 @@ describe('utils', () => {
api_type: 'governor-subgraph',
api_url:
'https://thegraph.com/hosted-service/subgraph/arr00/uniswap-governance-v2',
contract: 'sep:0x000000000000000000000000000000000000dead'
contract: '0x000000000000000000000000000000000000dead',
chain_id: 11155111
}
]
}
Expand Down
3 changes: 2 additions & 1 deletion apps/ui/src/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,8 @@ export function createErc1155Metadata(
name: delegation.name,
api_type: delegation.apiType,
api_url: delegation.apiUrl,
contract: `${delegation.contractNetwork}:${delegation.contractAddress}`
contract: delegation.contractAddress,
chain_id: delegation.chainId
})),
...extraProperties
}
Expand Down
1 change: 1 addition & 0 deletions apps/ui/src/helpers/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ ajv.addFormat('network', {
validate: () => true
});
ajv.addKeyword('networkId');
ajv.addKeyword('networksListKind');

function getErrorMessage(errorObject: Partial<ErrorObject>): string {
if (!errorObject.message) return 'Invalid field.';
Expand Down
23 changes: 17 additions & 6 deletions apps/ui/src/networks/common/graphqlApi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,17 +199,28 @@ function formatSpace(
return { id, name, description, color };
}),
delegations: space.metadata.delegations.map(delegation => {
const { name, api_type, api_url, contract } = JSON.parse(delegation);

const [network, address] = contract.split(':');
const { name, api_type, api_url, contract, chain_id } =
JSON.parse(delegation);

if (contract.includes(':')) {
// NOTE: Legacy format
const [network, address] = contract.split(':');

return {
name: name,
apiType: api_type,
apiUrl: api_url,
contractAddress: address === 'null' ? null : address,
chainId: CHAIN_IDS[network]
};
}

return {
name: name,
apiType: api_type,
apiUrl: api_url,
contractNetwork: network === 'null' ? null : network,
contractAddress: address === 'null' ? null : address,
chainId: CHAIN_IDS[network]
contractAddress: contract,
chainId: chain_id
};
}),
executors: space.metadata.executors,
Expand Down
2 changes: 1 addition & 1 deletion apps/ui/src/networks/evm/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ export function createActions(

if (delegationType === 'governor-subgraph') {
contractParams = {
address: delegationContract.split(':')[1],
address: delegationContract,
functionName: 'delegate',
functionParams: [delegatee],
abi: ['function delegate(address delegatee)']
Expand Down
2 changes: 0 additions & 2 deletions apps/ui/src/networks/offchain/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ function formatDelegations(space: ApiSpace): SpaceMetadataDelegation[] {
name,
apiType,
apiUrl: space.delegationPortal.delegationApi,
contractNetwork: null,
contractAddress: space.delegationPortal.delegationContract,
chainId
});
Expand All @@ -379,7 +378,6 @@ function formatDelegations(space: ApiSpace): SpaceMetadataDelegation[] {
name: 'Delegate registry',
apiType: 'delegate-registry',
apiUrl: DELEGATE_REGISTRY_URL,
contractNetwork: null,
contractAddress: space.id,
chainId
});
Expand Down
4 changes: 1 addition & 3 deletions apps/ui/src/networks/starknet/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,12 +688,10 @@ export function createActions(
) => {
await verifyStarknetNetwork(web3, chainId);

const [, contractAddress] = delegationContract.split(':');

const { account }: { account: Account } = web3.provider;

let calls: AllowArray<Call> = {
contractAddress,
contractAddress: delegationContract,
entrypoint: 'delegate',
calldata: CallData.compile({ delegatee })
};
Expand Down
3 changes: 1 addition & 2 deletions apps/ui/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@ export type SpaceMetadataDelegation = {
name: string | null;
apiType: DelegationType | null;
apiUrl: string | null;
contractNetwork: NetworkID | null;
contractAddress: string | null;
chainId?: ChainId | null;
chainId: ChainId | null;
};

export type SpaceMetadata = {
Expand Down

0 comments on commit accc9b4

Please sign in to comment.