Skip to content

Commit

Permalink
(registry) fix: multisig fix in service details (#89)
Browse files Browse the repository at this point in the history
* fix: update ipfs constant in NFT image list

* feat: add ethers v5

* feat: use ethersv5

* chore: add resolver for gnosis.pm - ethersv5

* refactor: update dependencies and improve transaction handling for ethersV5

* refactor: update eslint configuration to allow only console.warn and console.error

* chore: update CODEOWNERS

* test: works with gnosis-safe, yaygit status

* feat: remove all logs and update comment
  • Loading branch information
mohandast52 authored Aug 29, 2024
1 parent ecc53f1 commit 387f360
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 130 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
}
]
}
],
"no-console": [
"warn",
{
"allow": ["warn", "error"]
}
]
}
},
Expand Down
4 changes: 2 additions & 2 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# more info here - https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

apps/ @mohandast52 @oaksprout
libs/ @mohandast52 @oaksprout
apps/ @mohandast52 @oaksprout @Tanya-atatakai @truemiller
libs/ @mohandast52 @oaksprout @Tanya-atatakai @truemiller
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export const IpfsHashGenerationModal = ({
<span>
{/* TODO: fetch from middleware constant */}
<ul style={{ margin: 0 }}>
<li>{'ipfs://{IPFS_HASH}'}</li>
<li>ipfs://*</li>
<li>https://gateway.autonolas.tech/ipfs/*</li>
<li>https://gateway.pinata.cloud/ipfs/*</li>
<li>https://*.arweave.net/</li>
Expand Down
17 changes: 13 additions & 4 deletions apps/autonolas-registry/common-util/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { PublicKey } from '@solana/web3.js';
import { RuleObject } from 'antd/es/form';
import { StoreValue } from 'antd/es/form/interface';
import { Contract, FallbackProvider, JsonRpcProvider, ethers } from 'ethers';
import { Contract as ContractV5 } from 'ethers-v5';
import { isString } from 'lodash';
import { Address } from 'viem';

Expand All @@ -11,6 +12,7 @@ import {
isValidAddress,
notifyError,
notifyWarning,
sendTransaction as sendTransactionLegacyFn,
} from '@autonolas/frontend-library';

import { sendTransaction as sendTransactionFn } from 'libs/util-functions/src';
Expand Down Expand Up @@ -144,11 +146,11 @@ const isMethodsBuilderInstance = (
*
*/
export const sendTransaction = (
method: Contract,
method: Contract | ContractV5,
account: Address,
extra?: { vmType: string; registryAddress: Address },
extra?: { vmType: string; registryAddress: Address; isLegacy?: boolean },
) => {
const { vmType, registryAddress } = extra || {};
const { vmType, registryAddress, isLegacy } = extra || {};
if (vmType === VM_TYPE.SVM && registryAddress) {
// Check if something resembling an SVM method is being passed
if (!isMethodsBuilderInstance(method, registryAddress)) {
Expand All @@ -158,7 +160,14 @@ export const sendTransaction = (
return method.rpc();
}

return sendTransactionFn(method, account, {
if (isLegacy) {
return sendTransactionLegacyFn(method as ContractV5, account, {
supportedChains: SUPPORTED_CHAINS,
rpcUrls: RPC_URLS as RpcUrl,
});
}

return sendTransactionFn(method as Contract, account, {
supportedChains: SUPPORTED_CHAINS,
rpcUrls: RPC_URLS as RpcUrl,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { SVM_EMPTY_ADDRESS } from 'util/constants';
import { RadioLabel } from '../styles';
import { useFinishRegistration } from '../useSvmServiceStateManagement';
import { getServiceAgentInstances, onStep3Deploy } from '../utils';
import { handleMultisigSubmit } from './utils';
import { onMultisigSubmit } from './utils';

const STEP = 3;
const OPTION_1 = 'Creates a new service multisig with currently registered agent instances';
Expand Down Expand Up @@ -363,7 +363,7 @@ export const FinishedRegistration = ({
onClick={async () => {
try {
setIsSubmitting(true);
await handleMultisigSubmit({
await onMultisigSubmit({
multisig,
threshold,
agentInstances,
Expand All @@ -375,9 +375,9 @@ export const FinishedRegistration = ({
});
} catch (error) {
console.error(error);
notifyError('Error occurred while updating multisig. Please try again.');
} finally {
setIsSubmitting(false);
notifyError('Error occurred while updating multisig. Please try again.');
}
}}
{...getOtherBtnProps(STEP, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
/* eslint-disable no-underscore-dangle */
import { ethers } from 'ethers';
/**
* NOTE: Legacy code, needs to be refactored once gnosis.pm/safe-contracts updates ethers.js to v6
*
* How to test `onMultisigSubmit` function (step 3 in service)
* - First, you’ll need two accounts; let's call them `account1` and `account2`.
* - Create a service with account1 as the owner, using one 1 as an example.
* - Navigate to the newly created service.
* - Start with the first step and click the "Activate Registration" button.
* - In the second step, switch to `account2` and add `account1` as the "Agent instance address".
* - In the third step, switch back to `account1` and select 1st radio button (creates new multisig) and click the "Submit" button.
* - In the fourth step, use `account1` to "Terminate" the service.
* - In the fifth step, switch to `account2` and "Unbond" the service.
* NOW, start from the 1st step to test the multisig update functionality.
* - In the first step, switch to `account1` click "Activate Registration" button.
* - In the second step, switch to `account2` and add any valid address as the "Agent instance address" (fetch from the explorer of the same chain).
* - In the third step, switch back `account1` and select 2nd radio button and click "Submit" button - this will trigger the `onMultisigSubmit` function.
*
* NOTE: It's the same steps for gnosis-safe and metamask-like wallets.
*/
import { ethers } from 'ethers-v5';

import { getEthersProvider as getEthersV5Provider } from '@autonolas/frontend-library';

import { GNOSIS_SAFE_CONTRACT, MULTI_SEND_CONTRACT } from 'common-util/AbiAndAddresses';
import { RPC_URLS, getServiceOwnerMultisigContract } from 'common-util/Contracts';
import { safeMultiSend } from 'common-util/Contracts/addresses';
import { checkIfGnosisSafe, getEthersProvider } from 'common-util/functions';
import { SUPPORTED_CHAINS } from 'common-util/Login';
import { checkIfGnosisSafe } from 'common-util/functions';

import { isHashApproved } from './helpers';

Expand All @@ -28,7 +49,7 @@ const EIP712_SAFE_TX_TYPE = {
],
};

export const handleMultisigSubmit = async ({
export const onMultisigSubmit = async ({
multisig,
threshold,
agentInstances,
Expand All @@ -43,7 +64,6 @@ export const handleMultisigSubmit = async ({
GNOSIS_SAFE_CONTRACT.abi,
ethers.getDefaultProvider(RPC_URLS[chainId]),
);

const nonce = await multisigContract.nonce();

const callData = [];
Expand Down Expand Up @@ -84,12 +104,10 @@ export const handleMultisigSubmit = async ({
);

const safeTx = safeContracts.buildMultiSendSafeTx(multiSendContract, txs, nonce);

const provider = getEthersProvider();
const provider = getEthersV5Provider(SUPPORTED_CHAINS, RPC_URLS);
const isSafe = await checkIfGnosisSafe(account, provider);

try {
// TODO: check if we are dealing with safe in future!
// logic to deal with gnosis-safe
if (isSafe) {
// Create a message hash from the multisend transaction
Expand All @@ -105,7 +123,6 @@ export const handleMultisigSubmit = async ({
safeTx.refundReceiver,
nonce,
);

const multisigContractServiceOwner = getServiceOwnerMultisigContract(multisig);
const startingBlock = await provider.getBlockNumber();

Expand All @@ -126,7 +143,7 @@ export const handleMultisigSubmit = async ({
]);

// Redeploy the service updating the multisig with new owners and threshold
const packedData = ethers.solidityPacked(['address', 'bytes'], [multisig, safeExecData]);
const packedData = ethers.utils.solidityPack(['address', 'bytes'], [multisig, safeExecData]);

// Check if the hash was already approved
const filterOption = { approvedHash: messageHash, owner: account };
Expand All @@ -137,10 +154,10 @@ export const handleMultisigSubmit = async ({
fromBlock: 0,
toBlock: 'latest',
},
(_error, events) => {
async (_error, events) => {
// if hash was already approved, call the deploy function right away.
if (events.length > 0) {
handleStep3Deploy(radioValue, packedData);
await handleStep3Deploy(radioValue, packedData);
} else {
// else wait until the hash is approved and then call deploy function
multisigContractServiceOwner.methods
Expand All @@ -149,20 +166,18 @@ export const handleMultisigSubmit = async ({
.on('transactionHash', async (hash) => {
window.console.log('safeTx', hash);

// TODO: use websocket based subscription to fetch real-time event
// await until the hash is approved & then deploy
await isHashApproved(multisigContractServiceOwner, startingBlock, filterOption);
handleStep3Deploy(radioValue, packedData);
await handleStep3Deploy(radioValue, packedData);
})
.then((information) => window.console.log(information))
.catch((e) => {
console.error(e);
});
.catch((e) => console.error(e));
}
},
);
} else {
// logic to deal with metamask
}

// logic to deal with metamask like wallets
else {
const signer = provider.getSigner();

const getSignatureBytes = async () => {
Expand Down Expand Up @@ -196,7 +211,6 @@ export const handleMultisigSubmit = async ({
};

const signatureBytes = await getSignatureBytes();

const safeExecData = multisigContract.interface.encodeFunctionData('execTransaction', [
safeTx.to,
safeTx.value,
Expand All @@ -209,10 +223,9 @@ export const handleMultisigSubmit = async ({
safeTx.refundReceiver,
signatureBytes,
]);
const packedData = ethers.utils.solidityPack(['address', 'bytes'], [multisig, safeExecData]);

const packedData = ethers.solidityPacked(['address', 'bytes'], [multisig, safeExecData]);

handleStep3Deploy(radioValue, packedData);
await handleStep3Deploy(radioValue, packedData);
}
} catch (error) {
window.console.log('Error in signing:');
Expand Down
Loading

0 comments on commit 387f360

Please sign in to comment.