const repeatSVG = '<svg role="img" aria-labelledby="repeat" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><title id="circular">Repeated owner</title><path d="m17 2 4 4-4 4"/><path d="M3 11v-1a4 4 0 0 1 4-4h14"/><path d="m7 22-4-4 4-4"/><path d="M21 13v1a4 4 0 0 1-4 4H3"/><path d="M11 10h1v4"/></svg>';
async function getOwners(safe, rpc) {
+ const requests = {
+ ownersResult: '0xa0e67e2b', // getOwners()
+ thresholdResult: '0xe75235b8', // getThreshold()
+ requiredResult: '0xdc8452cd' // required()
+ }
+ const payload = [];
+ for (const [id, data] of Object.entries(requests)) {
+ payload.push({
+ jsonrpc: '2.0',
+ id,
+ method: 'eth_call',
+ params: [{ to: safe, data }, 'safe']
+ });
+ }
const response = await fetch(rpc, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify([
- {
- jsonrpc: '2.0',
- id: 'ownersResult',
- method: 'eth_call',
- params: [
- {
- to: safe,
- data: '0xa0e67e2b' // getOwners()
- },
- 'safe'
- ]
- },
- {
- jsonrpc: '2.0',
- id: 'thresholdResult',
- method: 'eth_call',
- params: [
- {
- to: safe,
- data: '0xe75235b8' // getThreshold()
- },
- 'safe'
- ]
- },
- {
- jsonrpc: '2.0',
- id: 'requiredResult',
- method: 'eth_call',
- params: [
- {
- to: safe,
- data: '0xdc8452cd' // required()
- },
- 'safe'
- ]
- }
- ])
+ body: JSON.stringify(payload)
}).then(r => r.json());
const { ownersResult, thresholdResult, requiredResult } = response.reduce((a, c) => ({ ...a, [c.id]: c.result }), {});
+
if (ownersResult === undefined) { // Smart contract reverted
return {
owners: [],