Skip to content

Commit

Permalink
if safes not supported, fail silently but show error in console
Browse files Browse the repository at this point in the history
  • Loading branch information
gsteenkamp89 committed Apr 17, 2024
1 parent cb5ca02 commit 9ade3ed
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 52 deletions.
51 changes: 30 additions & 21 deletions src/plugins/oSnap/Create.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ExtendedSpace, TreasuryWallet } from '@/helpers/interfaces';
import { ExtendedSpace } from '@/helpers/interfaces';
import { formatUnits } from '@ethersproject/units';
import { cloneDeep } from 'lodash';
import SelectSafe from './components/Input/SelectSafe.vue';
Expand All @@ -11,7 +11,8 @@ import {
Network,
OsnapPluginData,
Token,
Transaction
Transaction,
nonNullable
} from './types';
import {
getGnosisSafeBalances,
Expand Down Expand Up @@ -159,34 +160,42 @@ async function fetchCollectibles(network: Network, gnosisSafeAddress: string) {
// maps over the treasuries and creates a safe for each one
// only returns safes that have oSnap enabled
async function createOsnapEnabledSafes() {
const treasuriesWithOsnapEnabled = (
await Promise.all(
props.space.treasuries.map(async treasury => {
const isOsnapEnabled = await getIsOsnapEnabled(
treasury.network as Network,
treasury.address
);
return isOsnapEnabled ? treasury : null;
})
)
).filter(treasury => treasury !== null) as TreasuryWallet[];
const treasuryPromises = await Promise.allSettled(
props.space.treasuries.map(async treasury => {
const isOsnapEnabled = await getIsOsnapEnabled(
treasury.network as Network,
treasury.address
);
return isOsnapEnabled ? treasury : null;
})
);
const safes: GnosisSafe[] = await Promise.all(
const treasuriesWithOsnapEnabled = treasuryPromises
.map(res => (res.status === 'fulfilled' ? res.value : null))
.filter(nonNullable);
const safePromises = await Promise.allSettled(
treasuriesWithOsnapEnabled.map(async treasury => {
const moduleAddress = await getModuleAddressForTreasury(
treasury.network as Network,
treasury.address
);
return {
safeName: treasury.name,
safeAddress: toChecksumAddress(treasury.address),
network: treasury.network as Network,
transactions: [] as Transaction[],
moduleAddress
};
return moduleAddress
? {
safeName: treasury.name,
safeAddress: toChecksumAddress(treasury.address),
network: treasury.network as Network,
transactions: [] as Transaction[],
moduleAddress
}
: null;
})
);
const safes = safePromises
.map(res => (res.status === 'fulfilled' ? res.value : null))
.filter(nonNullable);
return safes;
}
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/oSnap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,3 +533,7 @@ export namespace GnosisSafe {
components?: ContractInput[];
}
}

export function nonNullable<T>(value: T): value is NonNullable<T> {
return value !== null;
}
92 changes: 61 additions & 31 deletions src/plugins/oSnap/utils/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
TransactionsProposedEvent
} from '../types';
import { getPagedEvents } from './events';
import { toChecksumAddress } from '@/helpers/utils';
import { shortenAddress, toChecksumAddress } from '@/helpers/utils';
import app from '../../../main';

/**
Expand All @@ -48,8 +48,8 @@ async function callGnosisSafeTransactionApi<TResult = any>(
network: Network,
url: string
) {
if(!GNOSIS_SAFE_TRANSACTION_API_URLS[network])
throw new Error(`No gnosis safe api defined for network ${network}`)
if (!GNOSIS_SAFE_TRANSACTION_API_URLS[network])
throw new Error(`No gnosis safe api defined for network ${network}`);
const apiUrl = GNOSIS_SAFE_TRANSACTION_API_URLS[network];
const response = await fetch(apiUrl + url);
return response.json() as TResult;
Expand Down Expand Up @@ -180,23 +180,35 @@ export const getModuleAddressForTreasury = async (
network: Network,
treasuryAddress: string
) => {
const subgraph = getOptimisticGovernorSubgraph(network);
const query = `
query getModuleAddressForTreasury {
safe(id: "${treasuryAddress.toLowerCase()}") {
optimisticGovernor {
id
try {
const subgraph = getOptimisticGovernorSubgraph(network);
const query = `
query getModuleAddressForTreasury {
safe(id: "${treasuryAddress.toLowerCase()}") {
optimisticGovernor {
id
}
}
}
}
`;
}
`;

type Result = {
safe: { optimisticGovernor: { id: string } };
};
type Result = {
safe: { optimisticGovernor: { id: string } };
};

const result = await queryGql<Result>(subgraph, query);
return result?.safe?.optimisticGovernor?.id ?? '';
const result = await queryGql<Result>(subgraph, query);
return result?.safe?.optimisticGovernor?.id ?? '';
} catch (error) {
console.error(
error instanceof Error
? error.message
: `Unable to get module address for treasury ${shortenAddress(
treasuryAddress
)} on network ${network}`
);

throw error;
}
};

/**
Expand All @@ -206,19 +218,30 @@ export const getIsOsnapEnabled = async (
network: Network,
safeAddress: string
) => {
const subgraph = getOptimisticGovernorSubgraph(network);
const query = `
query isOSnapEnabled {
safe(id:"${safeAddress.toLowerCase()}"){
isOptimisticGovernorEnabled
try {
const subgraph = getOptimisticGovernorSubgraph(network);
const query = `
query isOSnapEnabled {
safe(id:"${safeAddress.toLowerCase()}"){
isOptimisticGovernorEnabled
}
}
}
`;
type Result = {
safe: { isOptimisticGovernorEnabled: boolean };
};
const result = await queryGql<Result>(subgraph, query);
return result?.safe?.isOptimisticGovernorEnabled ?? false;
`;
type Result = {
safe: { isOptimisticGovernorEnabled: boolean };
};
const result = await queryGql<Result>(subgraph, query);
return result?.safe?.isOptimisticGovernorEnabled ?? false;
} catch (error) {
console.error(
error instanceof Error
? error.message
: `Unable to check if oSnap is enable for address ${shortenAddress(
safeAddress
)} on network ${network}`
);
throw error;
}
};

/**
Expand Down Expand Up @@ -672,7 +695,11 @@ export async function getOGProposalStateGql(params: {
}

// request execution if there is no settlement yet and liveness has expired
return { status: 'can-request-tx-execution', assertionHash, assertionLogIndex };
return {
status: 'can-request-tx-execution',
assertionHash,
assertionLogIndex
};
}

/**
Expand Down Expand Up @@ -746,7 +773,10 @@ export function getSafeNetworkPrefix(network: Network): SafeNetworkPrefix {
export function getSafeAppLink(
network: Network,
safeAddress: string,
{appUrl = 'https://app.safe.global', path = '/home' } = {appUrl: 'https://app.safe.global', path: '/home'}
{ appUrl = 'https://app.safe.global', path = '/home' } = {
appUrl: 'https://app.safe.global',
path: '/home'
}
) {
const prefix = getSafeNetworkPrefix(network);
return new URL(`${path}?safe=${prefix}:${safeAddress}`, appUrl).toString();
Expand Down

0 comments on commit 9ade3ed

Please sign in to comment.